summaryrefslogtreecommitdiffstats
path: root/lib/msun/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/msun/src')
-rw-r--r--lib/msun/src/k_tan.c27
-rw-r--r--lib/msun/src/k_tanf.c21
-rw-r--r--lib/msun/src/s_tan.c6
-rw-r--r--lib/msun/src/s_tanf.c6
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 */
OpenPOWER on IntegriCloud