I have the following piece of code:
#include <cstdio>
int main()
{
if ((1.0 + 0.1) != (1.0 + 0.1))
printf("not equal\n");
else
printf("equal\n");
return 0;
}
When compiled with O3 using gcc (4.4,4.5 and 4.6) and run natively (ubuntu 10.10), it prints the expected result of "equal".
However the same code when compiled as described above and run on a virtual machine (ubuntu 10.10, virtualbox image), it outputs "not equal" - this is the case for when the O3 and O2 flags are set however not O1 and below. When compiled with clang (O3 and O2) and run upon the virtual machine I get the correct result.
I understand 1.1 can't be correctly represented using double and I've read "What Every Computer Scientist Should Know About Floating-Point Arithmetic" so please don't point me there, this seems to be some kind of optimisation that GCC does that somehow doesn't seem to work in virtual machines.
Any ideas?
Note: The C++ standard says type promotion in this situations is implementation dependent, could it be that GCC is using a more precise internal representation that when the inequality test is applied holds true - due to the extra precision?
UPDATE1: The following modification of the above piece of code, now results in the correct result. It seems at some point, for whatever reason, GCC turns off floating point control word.
#include <cstdio>
void set_dpfpu() { unsigned int mode = 0x27F; asm ("fldcw %0" : : "m" (*&mode));
int main()
{
set_dpfpu();
if ((1.0 + 0.1) != (1.0 + 0.1))
printf("not equal\n");
else
printf("equal\n");
return 0;
}
UPDATE2: For those asking about the const expression nature of the code, I've changed it as follows, and still fails when compiled with GCC. - but i assume the optimizer may be turning the following into a const expression too.
#include <cstdio>
void set_dpfpu() { unsigned int mode = 0x27F; asm ("fldcw %0" : : "m" (*&mode));
int main()
{
//set_dpfpu(); uncomment to make it work.
double d1 = 1.0;
double d2 = 1.0;
if ((d1 + 0.1) != (d2 + 0.1))
printf("not equal\n");
else
printf("equal\n");
return 0;
}
UPDATE3 Resolution: Upgrading virtualbox to version 4.1.8r75467 resolved the issue. However the their remains one issue, that is: why was the clang build working.