In using double fmod(double x, double y)
and y
is an integer, the result appears to be always exact.
(That is y
a whole exact number, not meaning int
here.)
Maybe C does not require fmod()
to provide an exact answers in these select cases, but on compilers I've tried, the result is exact, even when the quotient of x/y
is not exactly representable.
y
is an integer? Examples:
double x = 1e10;
// x = 10000000000
printf("%.50g\n", fmod(x, 100));
// prints 0
x = 1e60;
// x = 999999999999999949387135297074018866963645011013410073083904
printf("%.50g\n", fmod(x, 100));
// prints 4
x = DBL_MAX;
// x = 179769313486231570...6184124858368
printf("%.50g\n", fmod(x, 100));
// prints 68
x = 123400000000.0 / 9999;
// x = 12341234.1234123408794403076171875
printf("%.50g %a\n", fmod(x, 100), fmod(x, 100));
// prints 34.1234123408794403076171875 0x1.10fcbf9cp+5
Notes:
My double
appears to the IEEE 754 binary64 compliant.
The limitations of printf()
are not at issue here, just fmod()
.
[Edit]
Note: By "Are exact answers expected", I was asking if the the fmod()
result and the mathematical result are exactly the same.
The result of fmod
is always exact; whether y
is an integer is irrelevant. Of course, if x
and/or y
are already approximations of some real numbers a
and b
, then fmod(x,y)
is unlikely to be exactly equal to a mod b
.
The IEEE Standard 754 defines the remainder operation x REM y
as the mathematical operation x - (round(x/y)*y)
. The result is exact by definition, even when the intermediate operations x/y
, round(x/y)
, etc. have inexact representations.
As pointed out by aka.nice, the definition above matches the library function remainder
in libm
. fmod
is defined in a different way, requiring that the result has the same sign as x
. However, since the difference between fmod
and remainder
is either 0
or y
, I believe that this still explains why the result is exact.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With