Reputation: 1047
I was playing around with the following piece of code
#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;
}
and noticed that, for the following input
15.1 1 1 1
it produces this (incorrect?) result on my machine
15.1 1 1 1
3
But it seems to produce this result on ideone (http://ideone.com/mwMalv)
15.1 1 1 1
0
I realize that "0.1" (in the "15) can't be represented accurately as a double
http://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/
but others that have run this code with gcc 4.8.2 also obtain what's produced on ideone.
I'm running Ubuntu 14.04.2 LTS Desktop (32-bit)
on VMware 6.0.5 build-2443746
with gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
.
What gives? Why does fmod
behave differently on my machine than it does on others (given the compiler's the same)?
Upvotes: 0
Views: 102
Reputation: 141633
Your calculations come out to approximately fmod(906, 3)
. However, 906
could be 905.9999999999998532
or something, due to errors with values not being exactly representable.
The result of fmod
with the latter than 3
will give 2.999999999999999998532
which will display as 3
when rounded to the default precision of 6
.
To see what is going on in detail, do << setprecision(30)
in your cout
statements.
It also might be illuminating to inspect the assembly output generated in each case. Perhaps the compilers are doing different things; or perhaps they are doing the same thing and the FPU is different.
For example, the result of the 906
might even be done in higher precision than double
. Changing your code to store this in a double
before going on to fmod
may or may not make a difference.
Upvotes: 1