This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Erratic behaviour of gcc/egcc on pentium


[This bug was reported to me as a co-maintainer of the Debian GNU/Linux EGCS
packages. Please Cc: 36876@bugs.debian.org in your response so it gets
archived in the Debian bugtracking system (http://www.debian.org/Bugs/).
Please Cc me as I'm not on the egcs-bugs list.]

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
platform.)

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

Details of versions etc:
------------------------

$ uname -a ;
Linux aspc30 2.0.36 #1 Mon Mar 29 12:46:14 IST 1999 i586 unknown

$ egcc -v ;
Reading specs from /usr/lib/gcc-lib/i486-linux/egcs-2.90.29/specs
gcc version egcs-2.90.29 980515 (egcs-1.0.3 release)

$ gcc -v ;
Reading specs from /usr/lib/gcc-lib/i486-linux/2.7.2.3/specs
gcc version 2.7.2.3

$ ld -v ;
GNU ld version 2.9.1 (with BFD 2.9.1)

$ ldd /usr/bin/gcc
        /lib/nfslock.so.0 => /lib/nfslock.so.0 (0x4000d000)
        libc.so.6 => /lib/libc.so.6 (0x40013000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

$ ldd /usr/bin/egcc
        /lib/nfslock.so.0 => /lib/nfslock.so.0 (0x4000d000)
        libc.so.6 => /lib/libc.so.6 (0x40013000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

--------------------------------------------------------
PLEASE ADVISE.
        -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);
                else            
                        printf("FALSE:\t%20.8E%20.8E%20.8E\n", x, q0, q);
        }
}

/*---------------------------------------------------------------------*/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]