diff options
author | das <das@FreeBSD.org> | 2004-06-02 04:39:29 +0000 |
---|---|---|
committer | das <das@FreeBSD.org> | 2004-06-02 04:39:29 +0000 |
commit | 75a66e7e89c8605786d7f5fe506e3a58d46c08a9 (patch) | |
tree | ad48881c46e6fcaecdce5ad4aa7e1922e9b37359 /lib/msun | |
parent | 576b26bafdee61ede4fafa63fd78e21930f5bc2e (diff) | |
download | FreeBSD-src-75a66e7e89c8605786d7f5fe506e3a58d46c08a9.zip FreeBSD-src-75a66e7e89c8605786d7f5fe506e3a58d46c08a9.tar.gz |
Merge a bugfix from FDLIBM 5.3 to ensure that the error in tan()
is always less than 1 ulp. Also update to the 5.3 license.
Obtained from: FDLIBM
Diffstat (limited to 'lib/msun')
-rw-r--r-- | lib/msun/src/k_tan.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/lib/msun/src/k_tan.c b/lib/msun/src/k_tan.c index bb7770d..b7cdf35 100644 --- a/lib/msun/src/k_tan.c +++ b/lib/msun/src/k_tan.c @@ -1,9 +1,8 @@ /* @(#)k_tan.c 5.1 93/09/24 */ /* * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. * - * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. @@ -77,14 +76,29 @@ __kernel_tan(double x, double y, int iy) int32_t ix,hx; GET_HIGH_WORD(hx,x); ix = hx&0x7fffffff; /* high word of |x| */ - if(ix<0x3e300000) /* x < 2**-28 */ - {if((int)x==0) { /* generate inexact */ - u_int32_t low; - GET_LOW_WORD(low,x); - if(((ix|low)|(iy+1))==0) return one/fabs(x); - else return (iy==1)? x: -one/x; - } - } + if(ix<0x3e300000) { /* x < 2**-28 */ + if ((int) x == 0) { /* generate inexact */ + u_int32_t low; + GET_LOW_WORD(low,x); + if (((ix | low) | (iy + 1)) == 0) + return one / fabs(x); + else { + if (iy == 1) + return x; + else { /* compute -1 / (x+y) carefully */ + double a, t; + + z = w = x + y; + SET_LOW_WORD(z, 0); + v = y - (z - x); + t = a = -one / w; + SET_LOW_WORD(t, 0); + s = one + t * z; + return t + a * (s + t * v); + } + } + } + } if(ix>=0x3FE59428) { /* |x|>=0.6744 */ if(hx<0) {x = -x; y = -y;} z = pio4-x; |