在使用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()结果和数学结果是否完全相同。

    最佳答案

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

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

    关于c - 当y为整数时,fmod()是否精确?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20928253/

    10-12 16:09