C 当y是整数时,fmod()精确吗?
使用C 当y是整数时,fmod()精确吗?,c,floating-point,C,Floating Point,使用double fmod(double x,double y)并且y是一个整数时,结果似乎总是精确的 (也就是说y是一个精确的整数,这里不表示int) 也许C不需要fmod()在这些选择的情况下提供准确的答案,但在我尝试过的编译器上,结果是准确的,即使x/y的商不能精确表示 当y为整数时,是否需要精确答案 如果没有,请提供一个反例 示例: double x = 1e10; // x = 10000000000 printf("%.50g\n", fmod(x, 100)); // prints
double fmod(double x,double y)
并且y
是一个整数时,结果似乎总是精确的
(也就是说y
是一个精确的整数,这里不表示int
)
也许C不需要fmod()
在这些选择的情况下提供准确的答案,但在我尝试过的编译器上,结果是准确的,即使x/y
的商不能精确表示
y
为整数时,是否需要精确答案李>
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
注:我的
double
显示为符合IEEE 754 binary64的版本。这里不讨论
printf()
的限制,只讨论fmod()
[编辑]
注:通过“是否需要精确答案”,我是问
fmod()
结果和数学结果是否完全相同 fmod的结果总是准确的;y
是否为整数无关紧要。当然,如果x
和/或y
已经是一些实数a
和b
的近似值,那么fmod(x,y)
不太可能完全等于a mod bIEEE标准754将余数运算x REM y
定义为数学运算x-(圆形)(x/y)*y)
。根据定义,即使中间操作x/y
、round(x/y)
等具有不精确的表示,结果也是精确的
正如aka.nice所指出的,上面的定义与libm
fmod
中的库函数余数
相匹配,以不同的方式定义,要求结果具有与x
相同的符号。然而,因为fmod
和余数
之间的差异是0
或y
,我相信这仍然可以解释为什么结果是精确的。这里“精确”是什么意思?就像“匹配数学结果”?你是对的。抱歉,比特sleepy@OliCharlesworth是,“匹配数学结果”+1引用。我想快速直观地解释为什么x-(轮(x/y)*y)
在原始精度范围内总是有一个精确的结果,但它太复杂了,所以我把它从我的答案中漏掉了。我认为没有一个简单的解释。天真地计算x轮(x/y)*对于我尝试过的一些极端情况(x=pow(2,53)*100
和y=100
),y
与fmod(x,y)
不同。实现必须执行迭代减法之类的技巧,以保持结果在数学上的精确性。我所知道的最佳解释是从减去r^n*y
开始,其中r
是基数,n
是产生结果的指数,其指数与x
的指数相同;这减少了n精度的位数至少为1,并产生一个与x
mody
一致的值。我怀疑您是通过归纳的方式应用此参数得出结论的,但细节(尤其是当符号翻转时)是一种痛苦。@R..下面的解释如何:让R
成为数学结果。x
和y
都是大于R
的浮点数,因此是ulp(R)
的倍数。因此R
是ulp(R)的倍数
,因此r
可以精确地表示为浮点数。@PascalCuoq:并不是所有的ulp(r)
的精确倍数都可以表示。例如,LLONG_MAX*ulp(r)
肯定不是。