[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Linking libc causes wrong results when casting double to long long
- To: bugs@openbsd.org
- Subject: Linking libc causes wrong results when casting double to long long
- From: Marcus Holland-Moritz <mhx-perl@gmx.net>
- Date: Sun, 25 Apr 2004 21:29:37 +0200
>Submitter-Id: net
>Originator: Marcus Holland-Moritz
>Organization:
net
>Synopsis: Linking libc causes wrong results when casting double to long long
>Severity: serious
>Priority: high
>Category: system
>Class: sw-bug
>Release: 3.4
>Environment:
<machine, os, target, libraries (multiple lines)>
System : OpenBSD 3.4
Architecture: OpenBSD.i386
Machine : i386
>Description:
When casting a double larger than 2**32 to an unsigned long long,
this gives correct results when _not_ linking libc, but _wrong_
results when linking libc.
>How-To-Repeat:
You can easily reproduce with the following snippet of C code
run under OpenBSD 3.3 and 3.4 (3.5 is identical to 3.4):
$ uname -a
OpenBSD openbsd33.mhxnet 3.3 GENERIC#44 i386
$ cat test.c
#include <stdio.h>
typedef double NV;
typedef unsigned long long UV;
int main(void)
{
NV f = 4294967303.15;
UV u = (UV) f;
printf("%f => %llu\n", f, u);
return 0;
}
$ cc -o test test.c && ./test
4294967303.150000 => 4294967303
$ cc -o test -lc test.c && ./test
4294967303.150000 => 4294967303
^^^^^^^^^^ CORRECT
$ uname -a
OpenBSD openbsd34.mhxnet 3.4 GENERIC#18 i386
$ cat test.c
#include <stdio.h>
typedef double NV;
typedef unsigned long long UV;
int main(void)
{
NV f = 4294967303.15;
UV u = (UV) f;
printf("%f => %llu\n", f, u);
return 0;
}
$ cc -o test test.c && ./test
4294967303.150000 => 4294967303
$ cc -o test -lc test.c && ./test
4294967303.150000 => 4294967304
^^^^^^^^^^ WRONG
>Fix:
Not sure what the root cause is, but the problem seems to have to do
with gcc's and libc's different implementations of __fixunsdfdi().