I hesitate to submit this, but I don't think this merits the usual "what do you expect from doubles?" response. This is with: Reading specs from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.1/specs Configured with: ../configure --prefix=/usr/local --enable- languages=c,c++,f77,objc,java,ada --enable-threads=posix --enable-shared -- enable-__cxa_atexit --with-system-zlib Thread model: posix gcc version 3.3.1 and the program: #include <stdio.h> int main () { double d = 0.1; double e = 5; double f = e / d; int i = (int) f; int j = (int) (e / d); printf ("f = %lf\n", f); printf ("i = %d\n", i); printf ("j = %d\n", j); return 0; } Notice that i and j are the integer result of 5 / 0.1 but that the intermediate double f is used to initialise i. I can just about except that 0.1 is represented by 0.10000000000000001 according to gdb. What does surprise me is that i and j can have different values: $ gcc double.cpp && ./a.out f = 50.000000 i = 50 j = 49 $ gcc -O double.cpp && ./a.out f = 50.000000 i = 50 j = 50 $ gcc -O -ffloat-store double.cpp && ./a.out f = 50.000000 i = 50 j = 49 As you can see, i != j unless I use raw optimisation. I can just about except that the result of the arithmetic is not exactly 50, but surely i should always be equal to j? In other words, I think i==j==50 or i==j==49 are correct outcomes but i!=j is not.
This is caused by x86's rounding modes and excessive precision so it is a dup of bug 323. *** This bug has been marked as a duplicate of 323 ***
Thanks for the quick response. I see that floating-point bugs are frequently raised and closed against 323. I'm not 100% sure it is exactly the same but 100% sure that I'm stuck. The suggestion for 323 is to use -ffloat-store. Unfortunately, for this problem it actually makes things worse (when used with optimisation) and makes no difference (when used without optimisation). It also suggests to change the fp rounding mode, but the gcc info doesn't seem to mention anything for that with x86. The M$ compiler has no problem with my code. How does it do it? How can I make gcc do it? If there is no way to make gcc do it, then surely it is a bug or at least a missing feature?