Is fmod incorrect?

Is fmod incorrect?

本文关键字:incorrect fmod Is      更新时间:2023-10-16

给定以下双精度,fmod是否返回正确的值?

    double x = .090;
    double y = .003;
    double r = fmod(x, y);
    // r = 0.0029999999999999949

为什么r不为0?

因为和大多数小数一样,这些数字不能用二进制浮点格式精确表示。查看实际使用的值:

#include <cstdio>
int main() {
    printf("%.20f %.20fn", .090, .003);
}
Output: 0.08999999999999999667 0.00300000000000000006

这些小的舍入误差意味着第一个值略小于第二个值的精确倍数,因此您可以看到结果。

您可能希望允许较小的误差容限:

if (r > y - some_small_value) {
    r = 0;
}

这类问题可以通过阅读题为每个计算机科学家应该知道的浮点运算的论文来解决。

您的机器对浮点数使用二进制表示,它不能准确地表示有理数3/1000=0.003。

当然,机器可以将其近似值0.003打印为"0.003",但这是通过printf内的格式化打印代码来完成的,当它将值四舍五入到给定的小数位数时。

浮点值的打印、十进制版本与其实际内部值之间的差异可能会给没有意识到这些问题的程序员或用户带来问题。