Bug 6900 - Floating point behaviour of gcc on pentium
Summary: Floating point behaviour of gcc on pentium
Status: RESOLVED DUPLICATE of bug 323
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: wrong-code
Depends on:
Reported: 2002-06-01 14:06 UTC by 36876
Modified: 2003-07-01 18:46 UTC (History)
2 users (show)

See Also:
Host: i386-linux
Known to work:
Known to fail:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description 36876 2002-06-01 14:06:00 UTC
[ Reported to the Debian BTS as report #36876.
  Please CC 36876@bugs.debian.org on replies.
  Log of report can be found at http://bugs.debian.org/36876 ]

The following program gives erratic/correct answers under different
conditions. The program is self explanatory.

The expected behaviour is to get the value of the variable 'q' to equal the
value of the variable 'shift' . Erratic behaviour refers to deviation from
this equality. The deviation can be controlled by increasing/decreasing the
value of 'factor' . The variable take GENERIC values.

The expected behaviour is seen on SGI and SPARC machines with their native
compilers and also with gcc (2.7x), with or without optimization.

On pentium with gcc/egcs the following happens:

Without optimization:	only those x which are powers of 2 give q = shift.
With optimization:	all give q = shift.

The deviations are NOT an artifact of printf formats. If subsequents
iterations are done with further code, these deviations actually get
amplified, and thus are genuine. In a non trivial code, this uncontrolled
error accumulation is a disaster.

While it is true that beyond 15 decimal places, one has garbage bits in the
internal representation, a suitable round-off/truncation etc should discard
these bits correctly and consistantly for generic values. (Other platforms
mentioned above seem to take care of this so also optimization on pentium

In another context, with a somewhat different program, the expected behaviour
resulted WITH-OUT optimization but WITH optimization, the behaviour was

	-G. Date (shyam@imsc.ernet.in)

# include <stdio.h>

main(argc, argv)
int argc;
char **argv ;

	double q, q0, x, factor, shift;

	factor = 100000000.000001L ; 	/* Choose any typical fraction */
	shift = 0.0L ;

	for(x = 0.0L; x < 257.0L; x = x + 1.0L )	{
		q0 = (factor)*x ;
		q =  q0 - factor*x + shift ;
		if( q == shift )
			printf(" TRUE:\t%20.8E%20.8E%20.8E\n", x, q0, q);
			printf("FALSE:\t%20.8E%20.8E%20.8E\n", x, q0, q);


Tim Prince commented:

report [case where an assignment sometimes rounds off to declared 
precision, sometimes not, according to chosen level of optimization]

               q0 = (factor)*x ;
                q =  q0 - factor*x + shift ;

Both egcs-2.96 and gcc-2.95.2 exhibit the reported behavior, where q0 is 
rounded to double when not optimized, so that q0 - factor*x is non-zero.  
When optimized, the same expression turns up zero.  From my personal point of 
view, I might expect the small change

                q =  q0 - (double)(factor*x) + shift ;

to make a difference, but it does not.

BTW, it is even more difficult to predict the result of this when running on 
machines without normal extended precision but with a multiply-accumulate 
instruction which does not round off between multiplication and subtraction.  
I assume that the C9X draft shows the committee's consensus that should be 
modified with the new math library functions if one wishes to produce 
predictable results in future versions of C in such a case.  


3.1 (Debian) (Debian unstable)

System: Debian GNU/Linux (unstable)
Architecture: i686
| Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name           Version        Description
ii  gcc-3.1        3.1-2          The GNU C compiler.
ii  binutils  The GNU assembler, linker and binary utiliti
ii  libc6          2.2.5-6        GNU C Library: Shared libraries and Timezone
host: i386-linux
configured with: /mnt/data/gcc-3.1/gcc-3.1-3.1ds2/src/configure -v --enable-languages=c,c++,java,f77,proto,objc,ada --prefix=/usr --mandir=$\(prefix\)/share/man --infodir=$\(prefix\)/share/info --with-gxx-include-dir=$\(prefix\)/include/g++-v3-3.1 --enable-shared --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --enable-clocale=gnu --enable-threads=posix --enable-java-gc=boehm --enable-objc-gc i386-linux
Comment 1 Wolfgang Bangerth 2002-12-04 07:01:59 UTC
State-Changed-From-To: open->closed
State-Changed-Why: Christian explained why.
Comment 2 Christian Ehrhardt 2002-12-04 15:51:45 UTC
From: "Christian Ehrhardt" <ehrhardt@mathematik.uni-ulm.de>
To: gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org, tprince@computer.org,
  sure@imsc.ernet.in, gcc-bugs@gcc.gnu.org, nobody@gcc.gnu.org,
  36876@bugs.debian.org, shyam@imsc.ernet.in
Subject: Re: c/6900: Floating point behaviour of gcc on pentium
Date: Wed, 4 Dec 2002 15:51:45 +0100

 This is not a bug. Comparing floating point numbers with == may yield
 unexpected results due to rounding errors. Someone please close this PR.
    regards  Christian
Comment 3 Andrew Pinski 2003-07-01 18:45:42 UTC
Reopening bug to mark bug as a dup of bug 323 so ...
Comment 4 Andrew Pinski 2003-07-01 18:46:05 UTC
that the number of dups goes up.

*** This bug has been marked as a duplicate of 323 ***