c++ fmod returns 0.2 for fmod(0.6,0.2)

c++ fmod returns 0.2 for fmod(0.6,0.2)

当我在 C++ 中使用 fmod(0.6,0.2) 时 returns 0.2

我知道这是由浮点精度引起的,但看来我现在必须得到两个双倍的余数

非常感谢对此类问题的任何解决方案

我认为最好的办法是使用余数函数而不是 fmod。对于给定的示例,它将 return 一个非常小的数字而不是 0.2。您可以使用此事实通过四舍五入到特定精度级别来假设余数为 0。

数学值 0.60.2 无法用二进制浮点数精确表示。

此演示程序将向您展示正在发生的事情:

#include <iostream>
#include <iomanip>
#include <cmath>
int main() {
    const double x = 0.6;
    const double y = 0.2;
    std::cout << std::setprecision(60)
              << "x          = " << x << "\n"
              << "y          = " << y << "\n"
              << "fmod(x, y) = " << fmod(x, y) << "\n";
}

我的系统(很可能是你的)的输出是:

x          = 0.59999999999999997779553950749686919152736663818359375
y          = 0.200000000000000011102230246251565404236316680908203125
fmod(x, y) = 0.1999999999999999555910790149937383830547332763671875

考虑到您传递给它的参数,fmod() 返回的结果是正确的。

如果您需要一些其他结果(我假设您期望 0.0),您将不得不做一些不同的事情。有多种可能性。您可以检查结果是否与 0.2 相差非常小,或者您可以使用整数算法进行计算(例如,如果您处理的所有数字都是 [=17= 的倍数) ] 或 0.01).

没错,问题是舍入误差。试试这个代码:

#include <stdio.h>
#include <math.h>
int main()
{
    double d6 = 0.6;
    double d2 = 0.2;
    double d = fmod (d6, d2);
    printf ("%30.20e %30.20e %30.20e\n", d6, d2, d);

}

当我在 gcc 4.4.7 中 运行 时,输出是:

5.99999999999999977796e-01     2.00000000000000011102e-01     1.99999999999999955591e-01

至于如何 "fix" 它,我不太清楚你到底想做什么,所以不知道该建议什么。总会有无法用浮点数精确表示的数字,所以这种行为是不可避免的。

有关问题域的更多信息将有助于获得更好的建议。例如,如果您处理的数字始终只有小数点后一位,并且足够小,则只需乘以 10,四舍五入到最接近的整数(或 long 或 long long),并使用 % 运算符而不是fmod 函数。如果您试图查看 fmod 的结果是否为 0.0,只需接受接近 0.2(在本例中)的结果,就好像它接近 0 一样。