[uClibc] Is there a workaround for this floating point bug?
Erik Andersen
andersen at codepoet.org
Sun Aug 10 03:46:13 UTC 2003
On Sat Aug 09, 2003 at 06:44:26PM -0700, David Wuertele wrote:
> The bug demonstrated by the program below is a showstopper for my
> project. If I can't fix it or find a workaround, I'll have to trash
> all my porting efforts and move back to glibc. Can anyone out there
> reproduce it? Does anyone have any ideas how I might work around it?
Are you _certain_ you do not see this with glibc? Did you
compile glibc yourself using the same compiler you are using for
uClibc. I suspect either your kernel or your compiler are
broken.
> Add equal parts mipsel, gcc-3.3, and uClibc to the program below and
> stir. Serve on your favorite embedded system.
BTW, you really do not need to post your test app three times.
Once was plenty... Your test app had a few little errors which I
fixed up. Several sucessful trial runs on my mipsel test box
follow. The last test is run inside the uClibc development
system for mips, available from the uClibc website.
$ uname -a
Linux phoenix 2.4.21-pre4 #1 Fri Jun 13 01:36:16 MDT 2003 mips unknown unknown GNU/Linux
$ cat /proc/cpuinfo
system type : MIPS Cobalt
processor : 0
cpu model : Nevada V10.0 FPU V10.0
BogoMIPS : 249.03
wait instruction : yes
microsecond timers : yes
tlb_entries : 48
extra interrupt vector : yes
hardware watchpoint : no
VCED exceptions : not available
VCEI exceptions : not available
$
$
$ cat test.c
#include <stdio.h>
int main ()
{
double thisdub = (double)0.1;
if (thisdub != (double)0.1) {
fprintf (stderr, "doubles are hosed!\n");
return 0;
}
fprintf (stderr, "if %f and %f don't both equal 0.100000,"
"suspect fprintf\n", (float)thisdub, (float)0.1);
unsigned long height1 = 120;
unsigned long height2 = 1200;
float scale1 = (float)height1 / (float)height2;
//double scale2 = (double)height1 / (double)height2;
double height3 = height2 * scale1;
unsigned long height4 = (unsigned long) height3;
fprintf (stderr, "if %f and %f aren't close to %lu, "
"suspect float operations\n",
(float)height3, (float)height4, height1);
return 0;
}
$ gcc --version | head -n1
gcc (GCC) 3.3 (Debian)
$ gcc -Wall -Os test.c -o test
$ ldd ./test
libc.so.6 => /lib/libc.so.6 (0x2ab04000)
/lib/ld.so.1 => /lib/ld.so.1 (0x2aaa8000)
$ ./test
if 0.100000 and 0.100000 don't both equal 0.100000, suspect fprintf
if 120.000000 and 120.000000 aren't close to 120, suspect float operations
$
$
$ /usr/mipsel-linux-uclibc/bin/mipsel-uclibc-gcc --version | head -n1
gcc-3.3 (GCC) 3.3 (Debian)
$ /usr/mipsel-linux-uclibc/bin/mipsel-uclibc-gcc -Wall -Os test.c -o test
$ ldd ./test
libc.so.0 => /usr/mipsel-linux-uclibc/lib/libc.so.0 (0x2aaee000)
ld-uClibc.so.0 => /usr/mipsel-linux-uclibc/lib/ld-uClibc.so.0 (0x2aaa8000)
$ ./test
if 0.100000 and 0.100000 don't both equal 0.100000, suspect fprintf
if 120.000000 and 120.000000 aren't close to 120, suspect float operations
$
$
$ cp test.c ~/CVS/buildroot/build_mipsel/root/root/
$ cd ~/CVS/buildroot/
$ sudo chroot build_mipsel/root
# gcc --version | head -n 1
gcc (GCC) 3.3
# ldd /usr/bin/gcc
libc.so.0 => /lib/libc.so.0 (0x2aaee000)
ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x2aaa8000)
# cd /root
# gcc -Wall -Os test.c -o test
# ./test
if 0.100000 and 0.100000 don't both equal 0.100000, suspect fprintf
if 120.000000 and 120.000000 aren't close to 120, suspect float operations
-Erik
--
Erik B. Andersen http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--
More information about the uClibc
mailing list