The comparison between 0 and the largest power of 2 that fits in a long double gives a non-zero result!!! Environment: System: OSF1 spe171.testdrive.hp.com V5.1 2650 alpha Architecture: alphaev56-dec-osf5.1 host: alphaev56-dec-osf5.1 build: alphaev56-dec-osf5.1 target: alphaev56-dec-osf5.1 configured with: ../configure How-To-Repeat: spe171.testdrive.hp.com> cat bug.c #include <stdio.h> #include <stdlib.h> #include <float.h> int main () { long double d; d = 1.0; while (d < LDBL_MAX / 2.0) d += d; printf ("d=%1.30Le\n", d); if (d == (long double) 0.0) printf ("d equals 0.0\n"); } spe171.testdrive.hp.com> gcc -O1 bug.c spe171.testdrive.hp.com> ./a.out d=5.948657476786158825428796633140e+4931 d equals 0.0
Please read http://gcc.gnu.org/bugs.html. Also have a look at bug 323 and its duplicates.
(In reply to comment #1) > Please read http://gcc.gnu.org/bugs.html. Also have a look at > bug 323 and its duplicates. Well, brushing off equality of 5*10^4931 and 0 as rounding error is maybe stretching it a bit ;-) This sure seems like a bug.
I just stumbled on the same problem, but with much more conventional numbers. The following C++ test program demonstrates it: #include <iostream> // this just serves to calculate a positive number which the optimizer // will not figure out at compile time long double f() { long double value = 1.0; for (int i = 0; i < 10; ++i) value += (long double)i; return value; } int main() { long double a = f(); std::cout << a; if (a > 0) std::cout << " > 0\n"; else if (a < 0) std::cout << " < 0\n"; else if (a == 0) std::cout << " == 0\n"; else std::cout << "oops!\n"; } Compiling and running gives: > g++ longdouble.cc -O3 && a.out 46 == 0 which is clearly wrong. The same result happens with -O2 and -O1. With -O0 I correctly get the output 46 > 0. The compiler is: > g++ -v Reading specs from /usr/local/lib/gcc-lib/alphaev67-dec-osf5.1/3.3/specs Configured with: ../gcc-3.3/configure --with-libiconv-prefix=/usr/local --with-included-gettext Thread model: single gcc version 3.3 As workaround for == 0, !! seems to work. Unfortunately I don't know a workaround for > 0 and < 0.
(In reply to comment #3) > As workaround for == 0, !! seems to work. Unfortunately I don't know a > workaround for > 0 and < 0. > Sorry for self-reply, but now I've found a simple workaround for all cases: Instead of comparing with 0, just add 1 and compare with 1. For some reason this works even if the number to compare with happens to be -1 (i.e. if after adding 1 you get 0).
Works on ev56 and ev67 linux-gnu with gcc 4.2 .. 4.5, assuming fixed.