c ++ fmod为fmod(0.6,0.2)返回0.2

时间:2016-07-18 23:49:51

标签: c++ floating-accuracy fmod

当我在c ++中使用fmod(0.6,0.2)时,它返回0.2

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

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

3 个答案:

答案 0 :(得分:2)

数学值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的差异非常小,或者您可以使用整数运算进行计算(例如,如果您处理的所有数字都是{{的倍数] 1}}或0.1)。

答案 1 :(得分:1)

我认为你最好的选择是使用余数函数而不是fmod。对于给定的示例,它将返回非常小的数字而不是0.2。您可以使用此事实通过舍入到某个精度级别来假设0的余数。

答案 2 :(得分:0)

你是对的,问题是舍入错误。试试这段代码:

#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

关于如何修复&#34;它,我不知道你究竟要做什么来知道建议什么。总会有一些数字无法用浮点精确表示,所以这种行为是不可避免的。

有关问题域的更多信息有助于获得更好的建议。例如,如果您使用的数字总是只有小数点后的一位数,并且足够小,只需乘以10,舍入到最接近的整数(或长或长),并使用%运算符而不是fmod功能。如果您试图查看fmod的结果是否为0.0,只需接受接近0.2的结果(在这种情况下),就好像接近0一样。