CodeKingPlusPlus
CodeKingPlusPlus

Reputation: 16081

C integer division and floor

In C, is there a difference between integer division a/b and floor(a/b) where both a and b are integers? More specifically what happens during both processes?

Upvotes: 23

Views: 95810

Answers (4)

ouah
ouah

Reputation: 145829

floor returns a double while a / b where both a and b are integers yields an integer value.

With the correct cast the value is the same.

If typeof operator existed in C (it does not) we would have:

(typeof (a /b)) floor(a / b) == a / b

EDIT: Now if the question is: is there any difference between:

(double) (a / b)

and

floor(a / (double) b)

the answer is yes. The results differ with respect to negative values.

Upvotes: 9

vinc17
vinc17

Reputation: 3466

In general, assuming that the integers are representable in both the integer and the floating-point types, there isn't a difference, but the proof is not obvious. The problem is that in floating-point, a rounding occurs in the division a/b, so that the floor function doesn't apply on the exact rational value, but on an approximate value. I had written a paper on the subject: https://www.vinc17.net/research/publi.html#Lef2005b

In short, the result I've obtained is that if a - b is exactly representable in the floating-point system, then floor(a/b), where a and b are floating-point numbers (with integer values), gives the same result as the integer division a/b.

Upvotes: 3

Pete Becker
Pete Becker

Reputation: 76295

a/b does integer division. If either a or b is negative, the result depends on the compiler (rounding can go toward zero or toward negative infinity in pre-C99; in C99+, the rounding goes toward 0). The result has type int. floor(a/b) does the same division, converts the result to double, discards the (nonexistent) fractional part, and returns the result as a double.

Upvotes: 24

Alan Curry
Alan Curry

Reputation: 14711

It's possible to lose information converting from integer to floating point. Not likely with int and double, but with slight alteration:

#include <stdio.h>
#include <math.h>

int main(void)
{
    unsigned long long a = 9000000000000000003;
    unsigned long long b = 3;
    printf("a/b = %llu\n", a/b);
    printf("floor(a/b) = %f\n", floor(a/b));
    return 0;
}

Result:

a/b = 3000000000000000001
floor(a/b) = 3000000000000000000.000000

Upvotes: 6

Related Questions