$ cat t.c #include <stdio.h> int main( int argc, char** argv ) { long long v1; sscanf( argv[1], "%lld", &v1 ); double d = (double)v1; long long v2 = (long long)d; printf( "v1=%lld d=%19.0f v2=%lld\n", v1, d, v2 ); return 0; } $ gcc -m32 -O -o t t.c $ t 9223372036854774781 v1=9223372036854774781 d=9223372036854774784 v2=9223372036854774781 please note that v1 == v2. This is wrong $ gcc -m32 -o t t.c $ t 9223372036854774781 v1=9223372036854774781 d=9223372036854774784 v2=9223372036854774784 v2 == d. This is correct -m64 (with or without optimisation) works too
(In reply to comment #0) > double d = (double)v1; Doesn't this overflow and provoke undefined behaviour when v1 is 9223372036854774781LL (0x7ffffffffffffbfd)?
You need to use -fexcess-precision=standard or -std=c99 on i?86, the default is -fexcess-precision=fast unless -std=c99 (even for -std=gnu99). Otherwise it might be evaluated with excess precision, and the number in question fits into the 80-bit long double just fine.
Okay thanks. This testcase is derived from C++ source. Using g++ -fexcess-precision=standard results in: cc1plus: sorry, unimplemented: -fexcess-precision=standard for C++ Can we change this bug to an enhancment request? I think I will use volatile then ...
For C++ you can use -ffloat-store (of course, the penalty for that is quite big). Or better -msse2 -mfpmath=sse if you don't need to support prehistoric HW.
-ffloat-store works. But I dont want to use it in our project. -msse2 -mfpmath=sse does not work. I still see fildll,fnstcw,... instructions in the assembler listing.
This is a dup of bug 323. *** This bug has been marked as a duplicate of bug 323 ***
I see no reference to -fexcess-precision=standard in (garbage sink) bug 323, do you? So IMHO this is not a dup.
On Sat, 1 Dec 2012, joerg.richter@pdv-fs.de wrote: > I see no reference to -fexcess-precision=standard in (garbage sink) bug 323, do > you? So IMHO this is not a dup. See comment 127 in that bug.