summaryrefslogtreecommitdiffstats
path: root/lib/msun
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2005-11-30 04:56:49 +0000
committerbde <bde@FreeBSD.org>2005-11-30 04:56:49 +0000
commit06d803185574a0ba37434b1e98b322e54cc32a4e (patch)
tree047b3755fd3ebbe004f5b45344c4282cec24c852 /lib/msun
parentfe2f3459f3077b7d5e548d1fea676788e4277c48 (diff)
downloadFreeBSD-src-06d803185574a0ba37434b1e98b322e54cc32a4e.zip
FreeBSD-src-06d803185574a0ba37434b1e98b322e54cc32a4e.tar.gz
Fixed the hi+lo approximation to log(2). The normal 17+24 bit decomposition
that was used doesn't work normally here, since we want to be able to multiply `hi' by the exponent of x _exactly_, and the exponent of x has more than 7 significant bits for most denormal x's, so the multiplication was not always exact despite a cloned comment claiming that it was. (The comment is correct in the double precision case -- with the normal 33+53 bit decomposition the exponent can have 20 significant bits and the extra bit for denormals is only the 11th.) Fixing this had little or no effect for denormals (I think because more precision is inherently lost for denormals than is lost by roundoff errors in the multiplication). The fix is to reduce the precision of the decomposition to 16+24 bits. Due to 2 bugs in the old deomposition and numerical accidents, reducing the precision actually increased the precision of hi+lo. The old hi+lo had about 39 bits instead of at least 41 like it should have had. There were off-by-1-bit errors in each of hi and lo, apparently due to mistranslation from the double precision hi and lo. The correct 16 bit hi happens to give about 19 bits of precision, so the correct hi+lo gives about 43 bits instead of at least 40. The end result is that expf() is now perfectly rounded (to nearest) except in 52561 cases instead of except in 67027 cases, and the maximum error is 0.5013 ulps instead of 0.5023 ulps.
Diffstat (limited to 'lib/msun')
-rw-r--r--lib/msun/src/e_expf.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/lib/msun/src/e_expf.c b/lib/msun/src/e_expf.c
index 5858d2c..b9eb0fc 100644
--- a/lib/msun/src/e_expf.c
+++ b/lib/msun/src/e_expf.c
@@ -27,10 +27,10 @@ huge = 1.0e+30,
twom100 = 7.8886090522e-31, /* 2**-100=0x0d800000 */
o_threshold= 8.8721679688e+01, /* 0x42b17180 */
u_threshold= -1.0397208405e+02, /* 0xc2cff1b5 */
-ln2HI[2] ={ 6.9313812256e-01, /* 0x3f317180 */
- -6.9313812256e-01,}, /* 0xbf317180 */
-ln2LO[2] ={ 9.0580006145e-06, /* 0x3717f7d1 */
- -9.0580006145e-06,}, /* 0xb717f7d1 */
+ln2HI[2] ={ 6.9314575195e-01, /* 0x3f317200 */
+ -6.9314575195e-01,}, /* 0xbf317200 */
+ln2LO[2] ={ 1.4286067653e-06, /* 0x35bfbe8e */
+ -1.4286067653e-06,}, /* 0xb5bfbe8e */
invln2 = 1.4426950216e+00, /* 0x3fb8aa3b */
P1 = 1.6666667163e-01, /* 0x3e2aaaab */
P2 = -2.7777778450e-03, /* 0xbb360b61 */
OpenPOWER on IntegriCloud