diff options
author | bde <bde@FreeBSD.org> | 2005-11-13 00:08:23 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 2005-11-13 00:08:23 +0000 |
commit | 3f7e4f15381a1bfc788cd99f2dcc2cb8a8f5b460 (patch) | |
tree | 113b81661953ed35da6d2286f1b2b903912de4d9 | |
parent | 1ec54e3e18695b221b2b9bd57cc1620acae29b8b (diff) | |
download | FreeBSD-src-3f7e4f15381a1bfc788cd99f2dcc2cb8a8f5b460.zip FreeBSD-src-3f7e4f15381a1bfc788cd99f2dcc2cb8a8f5b460.tar.gz |
Fixed some magic numbers.
The threshold for not being tiny was confusing and too small. Use the
usual 2**-12 threshold and simplify the algorithm slightly so that
this threshold works (now use the threshold for sinhf() instead of one
for 1+expm1()). This is just a small optimization.
The magic number 22 is log(DBL_EPSILON)/2 plus slop. This is bogus
for float precision. Use 9 (~log(FLT_EPSILON)/2 plus less slop than
for double precision).
The threshold for switching from returning exp(x)/2 to returning
exp(x/2)^2/2 was a little smaller than necessary. This was not quite
harmless since the exp(x/2)^2/2 case is inaccurate. Fixing it happens
to avoid accuracy problems for 2*6 of the 2*151 args that were handled
by the exp(x)/2 case. This leaves accuracy problems for about 2*19997
args near the overflow threshold (~89); the maximum error there is
2.5029 ulps.
There are also accuracy probles for args in +-[0.5*ln2, 9] -- 2*188885
args with errors of more than 1 ulp, with a maximum error of 1.384 ulps.
Fixed a syntax error and naming errors in pseudo-code in comments.
-rw-r--r-- | lib/msun/src/e_coshf.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/lib/msun/src/e_coshf.c b/lib/msun/src/e_coshf.c index d2368a6..ebd659e 100644 --- a/lib/msun/src/e_coshf.c +++ b/lib/msun/src/e_coshf.c @@ -38,20 +38,20 @@ __ieee754_coshf(float x) if(ix<0x3eb17218) { t = expm1f(fabsf(x)); w = one+t; - if (ix<0x24000000) return w; /* cosh(tiny) = 1 */ + if (ix<0x39800000) return one; /* cosh(tiny) = 1 */ return one+(t*t)/(w+w); } - /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ - if (ix < 0x41b00000) { + /* |x| in [0.5*ln2,9], return (exp(|x|)+1/exp(|x|))/2; */ + if (ix < 0x41100000) { t = __ieee754_expf(fabsf(x)); return half*t+half/t; } - /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ - if (ix < 0x42b17180) return half*__ieee754_expf(fabsf(x)); + /* |x| in [9, log(maxfloat)] return half*exp(|x|) */ + if (ix < 0x42b17217) return half*__ieee754_expf(fabsf(x)); - /* |x| in [log(maxdouble), overflowthresold] */ + /* |x| in [log(maxfloat), overflowthresold] */ if (ix<=0x42b2d4fc) { w = __ieee754_expf(half*fabsf(x)); t = half*w; |