Reputation: 16081
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
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
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
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
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