Re: ==operator gives unexpected result using -O0
Jakob Andreas Bærentzen wrote: It seems to me that if a,b, and c are float or double values and if a has been assigned b*c then a == (b*c) should return true since a should contain the same bitpattern as the temporary being assigned the value of b*c. Is it not so? This is the infamous x86 excess precision problem, which has been discussed in PR 323 and elsewhere. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 The problem is that the x87 FP register stack has 80 bit registers. Doubles are 64-bits. If you aren't careful (or if the compiler isn't), then you can end up comparing a full unrounded 80-bit value against a rounded 64-bit value, which will not be equal. Thus the result that you are seeing. There are various ways to work around this, but unfortunately, there is no good solution to the problem that makes everyone happy. The hardware design and the linux ABI design makes it difficult for the compiler to both get the right answer and give good performance. This problem has gone unsolved for well over a decade, and may never be solved. This problem can be avoided by using SSE registers instead of the x87 FP register stack. If you are running 64-bit linux on an AMD64/EM64T system, you won't have this problem, because they use the SSE registers by default. -- Jim Wilson, GNU Tools Support, http://www.specifix.com
==operator gives unexpected result using -O0
Hello, I do apologize if my ignorance is the problem here, but I am having a strange problem with the version of gcc included in suse 9.3: gcc version 3.3.5 20050117 (prerelease) (SUSE Linux). The same problem was observed with gcc 3.3.1. I have not tried later versions, but I can't find the problem in bugzilla so I assume it is either so trivial that I should be ashamed or unknown. It is an intel XEON processor. It seems to me that if a,b, and c are float or double values and if a has been assigned b*c then a == (b*c) should return true since a should contain the same bitpattern as the temporary being assigned the value of b*c. Is it not so? Never the less, the following piece of code does not work as expected when compiling with -O0. It works FINE when compiling with -O1 or higher. --- #include iostream using namespace std; int main() { double b = 9.5245435435564536; double c = 7.98786542345446565; double a = b*c; //Does not work. cout (a == (b*c)) endl; // Works double d = b*c; cout (a == d) endl; } --- With O0 the output is 0 1 With O1, O2 or O3 the output is 1 1 as one would expect. I have made a similar program in C and I also changed double to float. It makes no difference. Nor does the actual float/double values. The optimization flag seems to decide what happens. Any insight would be appreciated. Andreas