【问题标题】:Is fmod() exact when y is an integer?当 y 是整数时 fmod() 是否准确?
【发布时间】:2014-01-04 23:54:39
【问题描述】:

在使用 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

注意事项:
我的double 似乎符合 IEEE 754 binary64。
printf() 的限制在这里没有问题,只是fmod()


[编辑]

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

【问题讨论】:

  • 这里的“精确”是什么意思?如“匹配数学结果”?
  • 你是对的。抱歉,有点困
  • @OliCharlesworth 是的,“匹配数学结果”

标签: c floating-point


【解决方案1】:

fmod 的结果总是准确; y 是否为整数无关紧要。当然,如果x 和/或y 已经是一些实数ab 的近似值,那么fmod(x,y) 不太可能完全等于a mod b

【讨论】:

    【解决方案2】:

    IEEE 标准 754 将余数运算 x REM y 定义为数学运算 x - (round(x/y)*y)。根据定义,结果是精确的,即使中间操作x/yround(x/y) 等具有不精确的表示。

    正如aka.nice 所指出的,上面的定义与libm 中的库函数remainder 匹配。 fmod 以不同的方式定义,要求结果与x 具有相同的符号。但是,由于fmodremainder之间的区别是0y,我相信这仍然可以解释为什么结果是准确的。

    【讨论】:

    • 引用 +1。我一直在寻找一个快速直观的解释,说明为什么 x - (round(x/y)*y) 在原始精度内总是有一个准确的结果,但它变得太复杂了,所以我把它排除在我的答案之外。
    • 我不认为有一个简单的解释。对于我尝试过的一些极端情况(例如x = pow(2, 53)*100y = 100),天真地计算x-round(x/y)*yfmod(x, y) 不同。实现必须执行诸如迭代减法之类的技巧以保持结果在数学上准确。
    • 我知道的最好的解释是从减去r^n * y 开始,其中r 是基数,n 是产生结果的指数,其指数与x 的指数相同;这会将精度位置的数量减少至少一个,并产生一个与x mod y 一致的值。我怀疑你归纳地应用这个论点来得出结论,但是细节(尤其是当符号翻转时)是一个痛苦。
    • @R.. 那么下面的解释呢:设r 是数学结果。 xy 都是大于 r 的浮点数,因此是 ulp(r) 的倍数。因此rulp(r) 的倍数,因此r 完全可以表示为浮点数。
    • @PascalCuoq:并非ulp(r) 的所有精确倍数都是可表示的。例如,LLONG_MAX*ulp(r) 肯定不是。
    猜你喜欢
    • 1970-01-01
    • 2020-08-12
    • 2016-02-02
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    • 1970-01-01
    • 2012-03-19
    • 2021-11-12
    相关资源
    最近更新 更多