------- Comment #14 from pluto at agmk dot net 2010-03-24 13:59 ------- i've checked the Test0 from example a little on my intel Q9300 cpu.
first case: setup 32-bit code and break on libm.sin implementation. Breakpoint 1, main (argc=1, argv=0xffffe3c4) at t.c:74 (gdb) b sin Breakpoint 2 at 0xf7fa7110: file ../sysdeps/i386/fpu/s_sin.S, line 14. Test 0: (gdb) p testvalue $1 = 43998769152 Breakpoint 2, sin () at ../sysdeps/i386/fpu/s_sin.S:14 (gdb) bt #0 sin () at ../sysdeps/i386/fpu/s_sin.S:14 #1 0x08048682 in main (argc=1, argv=0xffffe3c4) at t.c:81 (gdb) info float =>R7: Valid 0x4022a3e87f0000000000 +43998769152 11x RCSID("$NetBSD: s_sin.S,v 1.5 1995/05/09 00:25:54 jtc Exp $") 12x 13x ENTRY(__sin) 14x fldl 4(%esp) 15x fxam 16x fstsw %ax 17x movb $0x45, %dh 18x andb %ah, %dh 19x cmpb $0x05, %dh 20x je 3f 21x 4: fsin <==== here we calculate Test0. 22t> fnstsw %ax 23x testl $0x400,%eax 24x jnz 1f 25x ret <==== and return... 26x .align ALIGNARG(4) 27x 1: fldpi 28x fadd %st(0) 29x fxch %st(1) 30x 2: fprem1 31x fnstsw %ax 32x testl $0x400,%eax 33x jnz 2b 34x fstp %st(1) 35x fsin 36x ret 37x 3: and the hardware result is: (gdb) info float =>R7: Valid 0xbfe38c41185b67ffffe4 -4.081936725100227664e-09 sin(43998769152.000000) (i.e. sin(0xa3e87f * 2^12)) is computed as -4.081937e-09 (-0x1.188230b6dp-28) It SHOULD be ~ -4.025292e-09 (-0x1.149dafd6b8987p-28) Relative error is 1.407% !!!! as you can see for 32-bit implementation there's *NO* smart argument range reduction. second case: setup 64-bit code. (gdb) break sin Breakpoint 2 at 0x7ffff7b79e00: file ../sysdeps/ieee754/dbl-64/s_sin.c, line 90. (gdb) c Test 0: Continuing. Breakpoint 2, __sin (x=43998769152) at ../sysdeps/ieee754/dbl-64/s_sin.c:90 and here's some kind of range reduction for -105414350 <|x|< 281474976710656. (gdb) fin Run till exit from #0 __sin (x=43998769152) at ../sysdeps/ieee754/dbl-64/s_sin.c:235 0x0000000000400882 in main (argc=1, argv=0x7fffffffe298) at t.c:81 Value returned is $1 = -4.0252920638371055e-09 sin(43998769152.000000) (i.e. sin(0xa3e87f * 2^12)) is computed as -4.025292e-09 (-0x1.149dafd6b8987p-28) It SHOULD be ~ -4.025292e-09 (-0x1.149dafd6b8987p-28) Relative error is 0.000e+00% finally, as you can see this NOT a gcc bug. it's a QOI bug in glibc ;) -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43490