当y是整数时,fmod()是否准确?

chu*_*ica 9 c floating-point

在使用double fmod(double x, double y)y是一个整数时,结果似乎总是精确的.

(这是y一个完全确切的数字,int在这里不是意思.)

也许C不要求 fmod()提供这些选择的情况下一个确切的答案,但我试过编译器,结果是准确的,即使当商x/y是不能准确地表示.

  1. y是整数时,是否预期确切的答案?
  2. 如果没有,请提供一个反例.

例子:

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
Run Code Online (Sandbox Code Playgroud)

注意:
double看来符合IEEE 754 binary64标准.
这里的局限性printf()并不是问题所在fmod().


[编辑]

注意:通过"预期的确切答案",我问的是fmod()结果和数学结果是否完全相同.

R..*_*R.. 11

结果fmod始终准确; 是否y整数是无关紧要的.当然,如果x和/或y已有一些实数的近似值ab,然后fmod(x,y)是不太可能完全相等a mod b.


Emi*_*lva 9

IEEE标准754将余数运算定义x REM y为数学运算x - (round(x/y)*y).其结果是准确的定义,即使中间业务x/y,round(x/y)等有不准确的陈述.

正如aka.nice指出,上面的定义相匹配的库函数remainderlibm.fmod以不同的方式定义,要求结果具有相同的符号x.然而,由于之间的差别fmod,并remainder要么是0y,我认为,这仍然解释了为什么结果是准确的.

  • 我不认为有一个简单的解释.对于我试过的一些极端情况,天真地计算`x-round(x/y)*y`与`fmod(x,y)`不同(`x = pow(2,53)*100`和`y =例如,100`.实现必须执行迭代减法等技巧,以保持结果在数学上精确. (2认同)
  • @R ..以下解释如何:让`r`成为数学结果.'x`和`y`都是大于`r`的浮点数,因此是`ulp(r)`的倍数.因此`r`是`ulp(r)`的倍数,因此`r`可以完全表示为浮点数. (2认同)