为什么fmod会产生不同的结果?

时间:2015-03-12 06:52:06

标签: c++ gcc g++ double modulus

我正在玩下面的代码

#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;

int main() {
    double speed = 60.0;
    double distance;
    int a, b, c;
    scanf("%lf %d %d %d", &distance, &a, &b, &c);

    cout << distance <<  " " << a << " " << b << " " << c << endl;
    cout << (fmod((distance*3600)/speed, (a + b + c))) << endl;
    return 0;
}

并注意到,对于以下输入

15.1 1 1 1

它在我的机器上产生了这个(不正确的?)结果

15.1 1 1 1
3

但似乎在ideone(http://ideone.com/mwMalv

上产生了这个结果
15.1 1 1 1
0

我意识到“0.1”(在“15”中)不能准确地表示为双重

http://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/

但是其他使用gcc 4.8.2运行此代码的人也获得了在ideone上生成的内容。

我正在使用Ubuntu 14.04.2 LTS Desktop (32-bit)VMware 6.0.5 build-2443746上运行gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

是什么给出的?为什么fmod在我的机器上的行为与在其他机器上的行为不同(假设编译器相同)?

1 个答案:

答案 0 :(得分:1)

您的计算结果大约为fmod(906, 3)。但是,906可能是905.9999999999998532或其他内容,因为错误的值无法准确表示。

fmod后者3的结果会给2.999999999999999998532,当舍入到默认精度3时,6会显示为<< setprecision(30)。< / p>

要详细了解详情,请在cout声明中906

检查每种情况下生成的装配输出也可能很有启发性。也许编译器正在做不同的事情;或者他们也在做同样的事情而且FPU是不同的。

例如,double的结果甚至可能比double的精度更高。在转到fmod之前更改代码以将其存储在{{1}}中可能会也可能不会产生影响。