Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is fmod() exact when y is an integer?

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.

  1. Are exact answers expected when y is an integer?
  2. If not, please supply a counter example.

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.

like image 603
chux - Reinstate Monica Avatar asked Jan 04 '14 23:01

chux - Reinstate Monica


2 Answers

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.

like image 157
R.. GitHub STOP HELPING ICE Avatar answered Sep 27 '22 00:09

R.. GitHub STOP HELPING ICE


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.

like image 32
Emilio Silva Avatar answered Sep 26 '22 00:09

Emilio Silva