>Number: 10902 >Category: c++ >Synopsis: comparing doubles is not consistent in gcc 3.3 (SuSE version) >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: wrong-code >Submitter-Id: net >Arrival-Date: Wed May 21 10:26:00 UTC 2003 >Closed-Date: >Last-Modified: >Originator: jos@vandenoever.info >Release: unknown-1.0 >Organization: >Environment: SuSE 8.2 i386 >Description: When comparing doubles without storing them in a temporary variable, the comparison can go wrong. The code below compares two doubles. One of them has value 1, the other has the value of the largest value below 1. When comparing these numbers, the difference is found. But when comparing these numbers without storing the result, the comparison is apparently performed in float precision. #include <iostream> using std::cout; using std::endl; #include <cfloat> int main() { double one = double(1); double belowone = double(1)-DBL_EPSILON; if (one == belowone) { cout << "one == belowone" << endl; } else { cout << "one != belowone" << endl; } if (double(1) == double(1) - DBL_EPSILON) { cout << "double(1) == double(1) - DBL_EPSILON" << endl; int i=1; while (double(1) == double(1) - i*DBL_EPSILON) ++i; cout << "double(1) == double(1) - "<<i-1<<"*DBL_EPSILON" << endl; cout << "This comparison is not OK!" << endl; } else { cout << "double(1) != double(1) - DBL_EPSILON" << endl; } return 0; } >How-To-Repeat: Compile the code given above. I find the bug with gcc version 3.3 20030226 (prerelease) (SuSE Linux), irrespective of using -O or -g. When using gcc version 2.95.3 20010315 (SuSE), the bug is not present. >Fix: >Release-Note: >Audit-Trail: >Unformatted:
The following reply was made to PR c++/10902; it has been noted by GNATS. From: Jos van den Oever <jos@vandenoever.info> To: gcc-gnats@gcc.gnu.org, nobody@gcc.gnu.org Cc: Subject: Re: c++/10902: comparing doubles is not consistent in gcc 3.3 (SuSE version) Date: Wed, 21 May 2003 13:34:16 +0200 Another addition to the report. Comparing doubles in c does work properly: #include <stdio.h> #include <float.h> int main() { double one = 1.0; double belowone = 1.0-DBL_EPSILON; if (one == belowone) { printf("one == belowone\n"); } else { printf("one != belowone\n"); } if (1.0 == 1.0 - DBL_EPSILON) { printf("1.0 == 1.0 - DBL_EPSILON\n"); } else { printf("1.0 != 1.0 - DBL_EPSILON\n"); } return 0; } gives output: one != belowone 1.0 != 1.0 - DBL_EPSILON
The following reply was made to PR c++/10902; it has been noted by GNATS. From: Jos van den Oever <jos@vandenoever.info> To: gcc-gnats@gcc.gnu.org, nobody@gcc.gnu.org, gcc-bugs@gcc.gnu.org Cc: Subject: Re: c++/10902: comparing doubles is not consistent in gcc 3.3 (SuSE version) Date: Wed, 21 May 2003 14:30:52 +0200 More info: The bug is not present in gcc version 3.2 (Mandrake Linux 9.0 3.2-1mdk).
Synopsis: comparing doubles is not consistent in gcc 3.3 (SuSE version) State-Changed-From-To: open->feedback State-Changed-By: bangerth State-Changed-When: Wed May 21 14:14:07 2003 State-Changed-Why: I get the same result for 3.2.3, 3.3 (release) and 3.4 (mainline): g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc g/x> ./a.out one != belowone double(1) != double(1) - DBL_EPSILON Could you possibly try with the 3.3 release, not with the snapshot SuSE is shipping? Thanks Wolfgang http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=10902
The following reply was made to PR c++/10902; it has been noted by GNATS. From: Jos van den Oever <jos@vandenoever.info> To: bangerth@dealii.org, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org, nobody@gcc.gnu.org, gcc-gnats@gcc.gnu.org Cc: Subject: Re: c++/10902: comparing doubles is not consistent in gcc 3.3 (SuSE version) Date: Wed, 21 May 2003 16:35:15 +0200 On Wednesday 21 May 2003 16:14, bangerth@dealii.org wrote: > Synopsis: comparing doubles is not consistent in gcc 3.3 (SuSE version) > > State-Changed-From-To: open->feedback > State-Changed-By: bangerth > State-Changed-When: Wed May 21 14:14:07 2003 > State-Changed-Why: > I get the same result for 3.2.3, 3.3 (release) and 3.4 > (mainline): > > g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc > g/x> ./a.out > one != belowone > double(1) != double(1) - DBL_EPSILON > > Could you possibly try with the 3.3 release, not with the > snapshot SuSE is shipping? I'm very glad to hear the bug is not present in the systems you tested. I'd like to install the released version of gcc 3.3, but as this is a production system I'm working on, I prefer to install rpms from SuSE. I do have an old laptop at home, but it's not capable of compiling gcc in a finite time. If there are any (SuSE or other reliable) rpms with gcc 3.3 I'm willing to test.
The following reply was made to PR c++/10902; it has been noted by GNATS. From: Wolfgang Bangerth <bangerth@ices.utexas.edu> To: Jos van den Oever <jos@vandenoever.info> Cc: gcc-bugs@gcc.gnu.org, <gcc-gnats@gcc.gnu.org> Subject: Re: c++/10902: comparing doubles is not consistent in gcc 3.3 (SuSE version) Date: Wed, 21 May 2003 09:41:09 -0500 (CDT) > I'd like to install the released version of gcc 3.3, but as this is a > production system I'm working on, I prefer to install rpms from SuSE. If you use ../gcc-3.3/configure --prefix=/some/local/path make bootstrap make install it will install gcc into /some/local/path, which could be a scratch directory in your homedir, or in /tmp. It won't overwrite any preinstalled files in /usr/... That's a safe way not to compromise the integrity of a production system. You can then run the compiler by setting PATH and LD_LIBRARY_PATH just for once in a shell window. > If there are any (SuSE or other reliable) rpms with gcc 3.3 I'm willing to > test. I have no clue. I'd think that SuSE might have one, but don't know. W. ------------------------------------------------------------------------- Wolfgang Bangerth email: bangerth@ices.utexas.edu www: http://www.ices.utexas.edu/~bangerth/
The following reply was made to PR c++/10902; it has been noted by GNATS. From: Jos van den Oever <jos@vandenoever.info> To: Wolfgang Bangerth <bangerth@ices.utexas.edu> Cc: gcc-bugs@gcc.gnu.org, <gcc-gnats@gcc.gnu.org> Subject: Re: c++/10902: comparing doubles is not consistent in gcc 3.3 (SuSE version) Date: Wed, 21 May 2003 16:54:19 +0200 On Wednesday 21 May 2003 16:41, you wrote: > If you use > ../gcc-3.3/configure --prefix=/some/local/path > make bootstrap > make install > it will install gcc into /some/local/path, which could be a scratch > directory in your homedir, or in /tmp. It won't overwrite any preinstalled > files in /usr/... That's a safe way not to compromise the integrity of a > production system. You can then run the compiler by setting PATH and > LD_LIBRARY_PATH just for once in a shell window. Ok, thanks for the instruction. It sounds safe to me, so I'll try it.