Date: Wed, 2 Nov 2005 05:37:32 +0000 (UTC) From: Bruce Evans <bde@FreeBSD.org> To: src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org Subject: cvs commit: src/lib/msun/src k_tanf.c Message-ID: <200511020537.jA25bWli044127@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
bde 2005-11-02 05:37:32 UTC FreeBSD src repository Modified files: lib/msun/src k_tanf.c Log: Fixed some of the silliness related to rev.1.8. In 1.8, "double" in a declaration was not translated to "float" although bit fiddling on double variables was translated. This resulted in garbage being put into the low word of one of the doubles instead of non-garbage being put into the only word of the intended float. This had no effect on any result because: - with doubles, the algorithm for calculating -1/(x+y) is unnecessarily complicated. Just returning -1/((double)x+y) would work, and the misdeclaration gave something like that except for messing up some low bits with the bit fiddling. - doubles have plenty of bits to spare so messing up some of the low bits is unlikely to matter. - due to other bugs, the buggy code is reached for a whole 4 args out of all 2**32 float args. The bug fixed by 1.8 only affects a small percentage of cases and a small percentage of 4 is 0. The 4 args happen to cause no problems without 1.8, so they are even less likely to be affected by the bug in 1.8 than average args; in fact, neither 1.8 nor this commit makes any difference to the result for these 4 args (and thus for all args). Corrections to the log message in 1.8: the bug only applies to tan() and not tanf(), not because the float type can't represent numbers large enough to trigger the problem (e.g., the example in the fdlibm-5.3 readme which is > 1.0e269), but because: - the float type can't represent small enough numbers. For there to be a possible problem, the original arg for tanf() must lie very near an odd multiple of pi/2. Doubles can get nearer in absolute units. In ulps there should be little difference, but ... - ... the cutoff for "small" numbers is bogus in k_tanf.c. It is still the double value (2**-28). Since this is 32 times smaller than FLT_EPSILON and large float values are not very uniformly distributed, only 6 args other than ones that are initially below the cutoff give a reduced arg that passes the cutoff (the 4 problem cases mentioned above and 2 non-problem cases). Fixing the cutoff makes the bug affect tanf() and much easier to detect than for tan(). With a cutoff of 2**-12 on amd64 with -O1, 670102 args pass the cutoff; of these, there are 337604 cases where there might be an error of >= 1 ulp and 5826 cases where there is such an error; the maximum error is 1.5382 ulps. The fix in 1.8 works with the reduced cutoff in all cases despite the bug in it. It changes the result in 84492 cases altogether to fix the 5826 broken cases. Fixing the fix by translating "double" to "float" changes the result in 42 cases relative to 1.8. In 24 cases the (absolute) error is increased and in 18 cases it is reduced, but it remains less than 1 ulp in all cases. Revision Changes Path 1.9 +1 -1 src/lib/msun/src/k_tanf.c
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200511020537.jA25bWli044127>