Article View: gnu.gcc.bug
Article #859GCC 1.36 sometimes misconverts large unsigned integers to float
From: Paul Eggert
Date: Fri, 08 Dec 1989 02:19
Date: Fri, 08 Dec 1989 02:19
71 lines
3177 bytes
3177 bytes
GCC 1.36 sometimes mishandles the conversion of unsigned values greater than
INT_MAX to floating point. For example, the program
#include <stdio.h>
main()
{
unsigned long L;
double D;
D = L = ~0;
printf("L=%lu, D=%g\n", L, D);
return 0;
}
should print something like "L=4294967295, D=4.29497e+09". Instead, D has
either the value 0 (Sun-3 -m68881, or Sun-4) or -1 (Sun-3 -msoft-float).
Looking at the generated code, there seem to be two different bugs depending
on whether -msoft-float is set. The 0 arises when GCC converts unsigned long
as if it were long, notices that the original number was negative, and
corrects by adding 1; it should correct by adding 4294967296. The -1 arises
because GCC uses __floatsidf to convert the unsigned long to double;
__floatsidf expects a signed long argument.
In the following transcripts, 'dry' is a Sun-3/60 running SunOS 4.0.3; 'rise'
is a SPARCstation 1 running SunOS 4.0.3c.
1-dry% gcc -v -m68881 t.c
gcc version 1.36
/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dmc68000 -Dsun -Dunix -D__mc68000__ -D
__sun__ -D__unix__ -D__HAVE_68881__ -Dmc68020 t.c /usr/tmp/cca20148.cpp
GNU CPP version 1.36
/local/lib/gcc-cc1 /usr/tmp/cca20148.cpp -quiet -dumpbase t.c -m68881 -version
-o /usr/tmp/cca20148.s
GNU C version 1.36 (68k, MIT syntax) compiled by GNU C version 1.36.
default target switches: -m68020 -mc68020 -mbitfield
as -mc68020 -o t.o /usr/tmp/cca20148.s
/local/lib/gcc-ld -e start -dc -dp /lib/crt0.o /lib/Mcrt1.o t.o /local/lib/gcc-
gnulib -lc
2-dry% ./a.out
L=4294967295, D=0
3-dry% gcc -v -msoft-float t.c
gcc version 1.36
/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dmc68000 -Dsun -Dunix -D__mc68000__ -D
__sun__ -D__unix__ -Dmc68020 t.c /usr/tmp/cca20154.cpp
GNU CPP version 1.36
/local/lib/gcc-cc1 /usr/tmp/cca20154.cpp -quiet -dumpbase t.c -msoft-float -ver
sion -o /usr/tmp/cca20154.s
GNU C version 1.36 (68k, MIT syntax) compiled by GNU C version 1.36.
default target switches: -m68020 -mc68020 -mbitfield
as -mc68020 -o t.o /usr/tmp/cca20154.s
/local/lib/gcc-ld -e start -dc -dp /lib/crt0.o /lib/Fcrt1.o t.o /local/lib/gcc-
gnulib -lc
4-dry% ./a.out
L=4294967295, D=-1
1-rise% gcc -v t.c
gcc version 1.36
/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__su
n__ -D__unix__ t.c /usr/tmp/cca01280.cpp
GNU CPP version 1.36
/local/lib/gcc-cc1 /usr/tmp/cca01280.cpp -quiet -dumpbase t.c -version -o /usr/
tmp/cca01280.s
GNU C version 1.36 (sparc) compiled by GNU C version 1.36.
default target switches: -mfpu -mepilogue
as -o t.o /usr/tmp/cca01280.s
/local/lib/gcc-ld -e start -dc -dp /lib/crt0.o t.o /local/lib/gcc-gnulib -lc
2-rise% ./a.out
L=4294967295, D=0
Technical Details
Message-ID:
<8912080219.AA01288@rise.twinsun.com>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!tut.cis.ohio-state.edu!twinsun.com!eggertShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!tut.cis.ohio-state.edu!twinsun.com!eggert From: eggert@twinsun.com (Paul Eggert) Newsgroups: gnu.gcc.bug Subject: GCC 1.36 sometimes misconverts large unsigned integers to float Message-ID: <8912080219.AA01288@rise.twinsun.com> Date: 8 Dec 89 02:19:07 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 71