diff options
Diffstat (limited to 'lib/msun/src')
-rw-r--r-- | lib/msun/src/k_tan.c | 27 | ||||
-rw-r--r-- | lib/msun/src/k_tanf.c | 21 | ||||
-rw-r--r-- | lib/msun/src/s_tan.c | 6 | ||||
-rw-r--r-- | lib/msun/src/s_tanf.c | 6 |
4 files changed, 14 insertions, 46 deletions
diff --git a/lib/msun/src/k_tan.c b/lib/msun/src/k_tan.c index 15145a6..13737d0 100644 --- a/lib/msun/src/k_tan.c +++ b/lib/msun/src/k_tan.c @@ -16,14 +16,16 @@ static char rcsid[] = "$FreeBSD$"; #endif /* __kernel_tan( x, y, k ) - * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854 + * kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854 * Input x is assumed to be bounded by ~pi/4 in magnitude. * Input y is the tail of x. * Input k indicates whether tan (if k = 1) or -1/tan (if k = -1) is returned. * * Algorithm * 1. Since tan(-x) = -tan(x), we need only to consider positive x. - * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0. + * 2. Callers must return tan(-0) = -0 without calling here since our + * odd polynomial is not evaluated in a way that preserves -0. + * Callers may do the optimization tan(x) ~ x for tiny x. * 3. tan(x) is approximated by a odd polynomial of degree 27 on * [0,0.67434] * 3 27 @@ -81,27 +83,6 @@ __kernel_tan(double x, double y, int iy) { 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 (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; diff --git a/lib/msun/src/k_tanf.c b/lib/msun/src/k_tanf.c index e344787..8e19309 100644 --- a/lib/msun/src/k_tanf.c +++ b/lib/msun/src/k_tanf.c @@ -45,27 +45,6 @@ __kernel_tanf(float x, float y, int iy) int32_t ix,hx; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; /* high word of |x| */ - if(ix<0x31800000) { /* x < 2**-28 */ - if ((int) x == 0) { /* generate inexact */ - { - if (iy == 1) - return x; - else { /* compute -1 / (x+y) carefully */ - float a, t; - - z = w = x + y; - GET_FLOAT_WORD(ix, z); - SET_FLOAT_WORD(z, ix & 0xfffff000); - v = y - (z - x); - t = a = -one / w; - GET_FLOAT_WORD(ix, t); - SET_FLOAT_WORD(t, ix & 0xfffff000); - s = one + t * z; - return t + a * (s + t * v); - } - } - } - } if(ix>=0x3f2ca140) { /* |x|>=0.6744 */ if(hx<0) {x = -x; y = -y;} z = pio4-x; diff --git a/lib/msun/src/s_tan.c b/lib/msun/src/s_tan.c index 5094d30..d707ecd 100644 --- a/lib/msun/src/s_tan.c +++ b/lib/msun/src/s_tan.c @@ -58,7 +58,11 @@ tan(double x) /* |x| ~< pi/4 */ ix &= 0x7fffffff; - if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1); + if(ix <= 0x3fe921fb) { + if(ix<0x3e300000) /* x < 2**-28 */ + if((int)x==0) return x; /* generate inexact */ + return __kernel_tan(x,z,1); + } /* tan(Inf or NaN) is NaN */ else if (ix>=0x7ff00000) return x-x; /* NaN */ diff --git a/lib/msun/src/s_tanf.c b/lib/msun/src/s_tanf.c index c81caaf..81c84e4 100644 --- a/lib/msun/src/s_tanf.c +++ b/lib/msun/src/s_tanf.c @@ -30,7 +30,11 @@ tanf(float x) /* |x| ~< pi/4 */ ix &= 0x7fffffff; - if(ix <= 0x3f490fda) return __kernel_tanf(x,z,1); + if(ix <= 0x3f490fda) { + if(ix<0x39800000) /* |x| < 2**-12 */ + if(((int)x)==0) return x; /* generate inexact */ + return __kernel_tanf(x,z,1); + } /* tan(Inf or NaN) is NaN */ else if (ix>=0x7f800000) return x-x; /* NaN */ |