[Bug c/43490] sin(x) (actually probably all trig) is inaccurate for large x
--- Comment #9 from simon dot fenney at imgtec dot com 2010-03-24 12:19 --- (In reply to comment #7) This is a glibc problem. Confirmed by LD_PRELOADing a different libm which makes it work. Please report to glibc bugzilla instead. The glibc team are saying that nothing has changed in the maths library (http://sourceware.org/bugzilla/show_bug.cgi?id=11422#c5) which brings me back here as it would appear that the only difference between the working and broken libraries are the versions of gcc used to compile them, e.g. working library: GNU C Library stable release version 2.3.4, by Roland McGrath et al. Compiled by GNU CC version 3.4.6 20060404 (Red Hat 3.4.6-11). example broken library: GNU C Library (EGLIBC) stable release version 2.10.1, gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9) -- simon dot fenney at imgtec dot com changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43490
[Bug c/43490] sin(x) (actually probably all trig) is inaccurate for large x
--- Comment #11 from simon dot fenney at imgtec dot com 2010-03-24 13:16 --- (In reply to comment #10) Both sin and sinf are assembly routines so can't probably be affected by the gcc used to compile them. See sysdeps/i386/fpu/s_sinf.S and sysdeps/i386/fpu/s_sin.S. I have not seen a working library for your testcase (2.9, built with GCC 4.3.2 is broken). Hmm. The last lot of code I saw was all generic c. Interesting This isn't a GCC bug but a glibc bug. Clearly glibc uses fsin out of specs. I can't see that *is* this issue unless fsin is also fundamentally broken. The Intel Instruction Set Reference states fsin works in the range -2^63 to +2^63 and I have just tested a value ~2^7 and got the following sin(1240093312.00) (i.e. sin(0x93d4a5 * 2^7)) is computed as -4.581222e-08 (-0x1.898622f829ffep-25) It SHOULD be ~ -4.581062e-08 (-0x1.8982a036335f2p-25) Relative error is 3.485e-03% That is dreadfully inaccurate and corresponds to about 15 bits accuracy instead of an expected result of about 52~53 bits for a double. Is there ANY way to get the gcc and glibc developers to talk directly to each other rather than have me ping-ponging back and forth between the two bugzilla databases? -- simon dot fenney at imgtec dot com changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43490
[Bug c/43490] sin(x) (actually probably all trig) is inaccurate for large x
--- Comment #12 from simon dot fenney at imgtec dot com 2010-03-24 13:18 --- (In reply to comment #11) (In reply to comment #10) and I have just tested a value ~2^7 and got the following Sorry I meant to say ~2^30 -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43490
[Bug c/43490] sin(x) (actually probably all trig) is inaccurate for large x
--- Comment #15 from simon dot fenney at imgtec dot com 2010-03-24 14:34 --- Thanks. I'll go back to the glibc bugzilla. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43490
[Bug c/43490] New: sin(x) (actually probably all trig) is inaccurate for large x
sin(x) (and sinf(x)) *used* to work accurately on earlier gcc versions, e.g. gcc 3.4.6 20060404 (Red Hat 3.4.6-9) ON x86_64-redhat-linux gcc 4.2.1 on Macintosh OR cross compiling for ARM Cortex-A8 with gcc version 4.3.2 BUT sin(x) becomes progressively more inaccurate with increasing magnitude of x, as with the above version (on x86). At a guess, it would seem like something has broken the range reduction maths. (Of course, it could be the source to the maths library that is broken but I can't tell if that is the case or whether it's the compiler that has broken it) Systems that were found to be broken: gcc 4.4.1 (Ubuntu 4.4.1-4ubuntu9) gcc 4.4.3 20100108 (prerelease) (Debian 4.4.2-9) GNU C 4.3.2 (i686-pc-linux-gnu) (Gentoo 4.3.2-r3 p1.6, pie-10.1.5 Build command: gcc -v -save-temps -o simplesintest -g -DDEBUG=1 -DDEBUG_INFO=1 -Wall -W -pedantic -std=c99 simplesintest.c -lm Command line: ./simplesintest Typical output is: = Test 0: sin(43998769152.00) (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% sinf(43998769152.00) (i.e. sinf(0xa3e87f * 2^12)) is computed as -4.081937e-09 (-0x1.18823p-28) It SHOULD be ~ -4.025292e-09 (-0x1.149dbp-28) Relative error is 1.407% Test 1: sin(9903547467890318699652972544.00) (i.e. sin(0x800017 * 2^70)) is computed as 2.763719e-01 (0x1.1b013a2290cc8p-2) It SHOULD be ~ 2.003433e-01 (0x1.9a4d9074cecaap-3) Relative error is -37.949% sinf(9903547467890318699652972544.00) (i.e. sinf(0x800017 * 2^70)) is computed as 2.763719e-01 (0x1.1b013ap-2) It SHOULD be ~ 2.003433e-01 (0x1.9a4d9p-3) Relative error is -37.949% Test 2: sin(8773115793420245409943394342404096.00) (i.e. sin(0xd84625 * 2^89)) is computed as 7.399661e-01 (0x1.7adcd596e1d56p-1) It SHOULD be ~ 2.044974e-08 (0x1.5f52ea84f120cp-26) Relative error is -3618461696.000% sinf(8773115793420245409943394342404096.00) (i.e. sinf(0xd84625 * 2^89)) is computed as 7.399661e-01 (0x1.7adcd6p-1) It SHOULD be ~ 2.044974e-08 (0x1.5f52eap-26) Relative error is -3618461696.000% Test 3: sin(10633823966279326983230456482242756608.00) (i.e. sin(0x80 * 2^100)) is computed as -7.480374e-01 (-0x1.7efec078c6a44p-1) It SHOULD be ~ -4.205416e-02 (-0x1.5881f6eeb6a8dp-5) Relative error is 1678.748% sinf(10633823966279326983230456482242756608.00) (i.e. sinf(0x80 * 2^100)) is computed as -7.480373e-01 (-0x1.7efecp-1) It SHOULD be ~ -4.205416e-02 (-0x1.5881f6p-5) Relative error is 1678.748% = -- Summary: sin(x) (actually probably all trig) is inaccurate for large x Product: gcc Version: 4.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: simon dot fenney at imgtec dot com GCC build triplet: ??? GCC host triplet: i486-linux-gnu GCC target triplet: i486-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43490
[Bug c/43490] sin(x) (actually probably all trig) is inaccurate for large x
--- Comment #1 from simon dot fenney at imgtec dot com 2010-03-23 12:06 --- Created an attachment (id=20168) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=20168action=view) Trivial test program that outputs sin(x) and sinf(x) for various vals VS expected results I haven't added tests for cos or tan etc, but I expect they will be broken as well. *My guess* is that the range reduction that gets X down to the equivalent in the range [0, Pi/2] or [0, Pi/4] has broken as the errors get worse with increasing x. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43490
[Bug c/43490] sin(x) (actually probably all trig) is inaccurate for large x
--- Comment #3 from simon dot fenney at imgtec dot com 2010-03-23 12:20 --- (In reply to comment #2) duplicate of PR43405. It's doesn't seem to be the same. I just tried the test source from 43405 and on the old system (gcc 3.4.6) (which I assumed was working) got: double precision: sin(1e22) = -0.8522008497671888 quad precison: sin(1e22)=0.4626130407646018 while on the systems I was worried about, got double precision: sin(1e22) = 0.4626130407646017 quad precison: sin(1e22)=0.4626130407646018 Using maple and computing the result to 30 decimal places, I get -.852200849767188801772705893753 so it looks like there is an additional problem. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43490
[Bug c/43490] sin(x) (actually probably all trig) is inaccurate for large x
--- Comment #5 from simon dot fenney at imgtec dot com 2010-03-23 13:10 --- (In reply to comment #4) BUT sin(x) becomes progressively more inaccurate with increasing magnitude of x, as with the above version (on x86). At a guess, it would seem like something has broken the range reduction maths. Since pi is irrational, range reduction is inherently broken for large x. Try to compute sin(x) for a large value of x and its nearest values from below and above. Yes, I am aware of that, but the *standard* seems to be to assume that the source value is accurate, compute the range reduced result to sufficient precision, and then compute sine/cosine to the required ULP accuracy. (e.g. see Payne-Hanek reduction algorithm or any of the newer methods such as ftp://ftp.inria.fr/INRIA/publication/dienst/RR-4267.pdf). It was working on earlier incarnations so is frustrating that it's now broken. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43490
[Bug c/43490] sin(x) (actually probably all trig) is inaccurate for large x
--- Comment #8 from simon dot fenney at imgtec dot com 2010-03-23 13:37 --- (In reply to comment #6) you can test two different implementations: 1). '-O2 -m32 -fno-builtin' - force libm.so calls and test libc implementation. 2). '-O2 -m32' to test gcc compile-time evaluation. FWIW I've just tried gcc -o simplesintest -Wall -W -pedantic -std=c99 simplesintest.c -O2 -m32 -fno-builtin -lm and gcc -o simplesintest -Wall -W -pedantic -std=c99 simplesintest.c -O2 -m32 -lm and they've made no difference :-| -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43490