aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/ieee754
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2012-03-02 20:51:39 +0000
committerJoseph Myers <joseph@codesourcery.com>2012-03-02 20:51:39 +0000
commit804360ed837e3347c9cd9738f25345d2587a1242 (patch)
treee2e9d62c3198feedb7dbd8c8ac5ff1bf0bf66275 /sysdeps/ieee754
parenta6d06d7b86f724046b462115556d0df682f9f703 (diff)
downloadglibc-804360ed837e3347c9cd9738f25345d2587a1242.tar
glibc-804360ed837e3347c9cd9738f25345d2587a1242.tar.gz
glibc-804360ed837e3347c9cd9738f25345d2587a1242.tar.bz2
glibc-804360ed837e3347c9cd9738f25345d2587a1242.zip
Fix sin, cos, tan in non-default rounding modes (bug 3976).
Diffstat (limited to 'sysdeps/ieee754')
-rw-r--r--sysdeps/ieee754/dbl-64/s_sin.c109
-rw-r--r--sysdeps/ieee754/dbl-64/s_tan.c117
2 files changed, 143 insertions, 83 deletions
diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c
index 5b79854004..32ba66d1a0 100644
--- a/sysdeps/ieee754/dbl-64/s_sin.c
+++ b/sysdeps/ieee754/dbl-64/s_sin.c
@@ -53,6 +53,7 @@
#include "usncs.h"
#include "MathLib.h"
#include "math_private.h"
+#include <fenv.h>
#ifndef SECTION
# define SECTION
@@ -107,12 +108,16 @@ __sin(double x){
#if 0
int4 nn;
#endif
+ fenv_t env;
+ double retval = 0;
+
+ libc_feholdexcept_setround (&env, FE_TONEAREST);
u.x = x;
m = u.i[HIGH_HALF];
k = 0x7fffffff&m; /* no sign */
if (k < 0x3e500000) /* if x->0 =>sin(x)=x */
- return x;
+ { retval = x; goto ret; }
/*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/
else if (k < 0x3fd00000){
xx = x*x;
@@ -120,7 +125,8 @@ __sin(double x){
t = ((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*(xx*x);
res = x+t;
cor = (x-res)+t;
- return (res == res + 1.07*cor)? res : slow(x);
+ retval = (res == res + 1.07*cor)? res : slow(x);
+ goto ret;
} /* else if (k < 0x3fd00000) */
/*---------------------------- 0.25<|x|< 0.855469---------------------- */
else if (k < 0x3feb6000) {
@@ -137,7 +143,8 @@ __sin(double x){
cor=(ssn+s*ccs-sn*c)+cs*s;
res=sn+cor;
cor=(sn-res)+cor;
- return (res==res+1.096*cor)? res : slow1(x);
+ retval = (res==res+1.096*cor)? res : slow1(x);
+ goto ret;
} /* else if (k < 0x3feb6000) */
/*----------------------- 0.855469 <|x|<2.426265 ----------------------*/
@@ -163,7 +170,8 @@ __sin(double x){
cor=(ccs-s*ssn-cs*c)-sn*s;
res=cs+cor;
cor=(cs-res)+cor;
- return (res==res+1.020*cor)? ((m>0)?res:-res) : slow2(x);
+ retval = (res==res+1.020*cor)? ((m>0)?res:-res) : slow2(x);
+ goto ret;
} /* else if (k < 0x400368fd) */
/*-------------------------- 2.426265<|x|< 105414350 ----------------------*/
@@ -189,7 +197,8 @@ __sin(double x){
res = a+t;
cor = (a-res)+t;
cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
- return (res == res + cor)? res : sloww(a,da,x);
+ retval = (res == res + cor)? res : sloww(a,da,x);
+ goto ret;
}
else {
if (a>0)
@@ -210,7 +219,8 @@ __sin(double x){
res=sn+cor;
cor=(sn-res)+cor;
cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
- return (res==res+cor)? ((m)?res:-res) : sloww1(a,da,x);
+ retval = (res==res+cor)? ((m)?res:-res) : sloww1(a,da,x);
+ goto ret;
}
break;
@@ -232,7 +242,8 @@ __sin(double x){
res=cs+cor;
cor=(cs-res)+cor;
cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
- return (res==res+cor)? ((n&2)?-res:res) : sloww2(a,da,x,n);
+ retval = (res==res+cor)? ((n&2)?-res:res) : sloww2(a,da,x,n);
+ goto ret;
break;
@@ -268,7 +279,8 @@ __sin(double x){
res = a+t;
cor = (a-res)+t;
cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
- return (res == res + cor)? res : bsloww(a,da,x,n);
+ retval = (res == res + cor)? res : bsloww(a,da,x,n);
+ goto ret;
}
else {
if (a>0) {m=1;t=a;db=da;}
@@ -287,7 +299,8 @@ __sin(double x){
res=sn+cor;
cor=(sn-res)+cor;
cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
- return (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
+ retval = (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
+ goto ret;
}
break;
@@ -309,7 +322,8 @@ __sin(double x){
res=cs+cor;
cor=(cs-res)+cor;
cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
- return (res==res+cor)? ((n&2)?-res:res) : bsloww2(a,da,x,n);
+ retval = (res==res+cor)? ((n&2)?-res:res) : bsloww2(a,da,x,n);
+ goto ret;
break;
@@ -323,17 +337,20 @@ __sin(double x){
n = __branred(x,&a,&da);
switch (n) {
case 0:
- if (a*a < 0.01588) return bsloww(a,da,x,n);
- else return bsloww1(a,da,x,n);
+ if (a*a < 0.01588) retval = bsloww(a,da,x,n);
+ else retval = bsloww1(a,da,x,n);
+ goto ret;
break;
case 2:
- if (a*a < 0.01588) return bsloww(-a,-da,x,n);
- else return bsloww1(-a,-da,x,n);
+ if (a*a < 0.01588) retval = bsloww(-a,-da,x,n);
+ else retval = bsloww1(-a,-da,x,n);
+ goto ret;
break;
case 1:
case 3:
- return bsloww2(a,da,x,n);
+ retval = bsloww2(a,da,x,n);
+ goto ret;
break;
}
@@ -343,9 +360,13 @@ __sin(double x){
else {
if (k == 0x7ff00000 && u.i[LOW_HALF] == 0)
__set_errno (EDOM);
- return x / x;
+ retval = x / x;
+ goto ret;
}
- return 0; /* unreachable */
+
+ ret:
+ libc_feupdateenv (&env);
+ return retval;
}
@@ -362,11 +383,16 @@ __cos(double x)
mynumber u,v;
int4 k,m,n;
+ fenv_t env;
+ double retval = 0;
+
+ libc_feholdexcept_setround (&env, FE_TONEAREST);
+
u.x = x;
m = u.i[HIGH_HALF];
k = 0x7fffffff&m;
- if (k < 0x3e400000 ) return 1.0; /* |x|<2^-27 => cos(x)=1 */
+ if (k < 0x3e400000 ) { retval = 1.0; goto ret; } /* |x|<2^-27 => cos(x)=1 */
else if (k < 0x3feb6000 ) {/* 2^-27 < |x| < 0.855469 */
y=ABS(x);
@@ -383,7 +409,8 @@ __cos(double x)
cor=(ccs-s*ssn-cs*c)-sn*s;
res=cs+cor;
cor=(cs-res)+cor;
- return (res==res+1.020*cor)? res : cslow2(x);
+ retval = (res==res+1.020*cor)? res : cslow2(x);
+ goto ret;
} /* else if (k < 0x3feb6000) */
@@ -397,7 +424,8 @@ __cos(double x)
res = a+t;
cor = (a-res)+t;
cor = (cor>0)? 1.02*cor+1.0e-31 : 1.02*cor -1.0e-31;
- return (res == res + cor)? res : csloww(a,da,x);
+ retval = (res == res + cor)? res : csloww(a,da,x);
+ goto ret;
}
else {
if (a>0) {m=1;t=a;db=da;}
@@ -416,7 +444,8 @@ __cos(double x)
res=sn+cor;
cor=(sn-res)+cor;
cor = (cor>0)? 1.035*cor+1.0e-31 : 1.035*cor-1.0e-31;
- return (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
+ retval = (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
+ goto ret;
}
} /* else if (k < 0x400368fd) */
@@ -443,7 +472,8 @@ __cos(double x)
res = a+t;
cor = (a-res)+t;
cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
- return (res == res + cor)? res : csloww(a,da,x);
+ retval = (res == res + cor)? res : csloww(a,da,x);
+ goto ret;
}
else {
if (a>0) {m=1;t=a;db=da;}
@@ -462,7 +492,8 @@ __cos(double x)
res=sn+cor;
cor=(sn-res)+cor;
cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
- return (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
+ retval = (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
+ goto ret;
}
break;
@@ -483,7 +514,8 @@ __cos(double x)
res=cs+cor;
cor=(cs-res)+cor;
cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
- return (res==res+cor)? ((n)?-res:res) : csloww2(a,da,x,n);
+ retval = (res==res+cor)? ((n)?-res:res) : csloww2(a,da,x,n);
+ goto ret;
break;
@@ -518,7 +550,8 @@ __cos(double x)
res = a+t;
cor = (a-res)+t;
cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
- return (res == res + cor)? res : bsloww(a,da,x,n);
+ retval = (res == res + cor)? res : bsloww(a,da,x,n);
+ goto ret;
}
else {
if (a>0) {m=1;t=a;db=da;}
@@ -537,7 +570,8 @@ __cos(double x)
res=sn+cor;
cor=(sn-res)+cor;
cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
- return (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
+ retval = (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
+ goto ret;
}
break;
@@ -558,7 +592,8 @@ __cos(double x)
res=cs+cor;
cor=(cs-res)+cor;
cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
- return (res==res+cor)? ((n)?-res:res) : bsloww2(a,da,x,n);
+ retval = (res==res+cor)? ((n)?-res:res) : bsloww2(a,da,x,n);
+ goto ret;
break;
}
@@ -570,17 +605,20 @@ __cos(double x)
n = __branred(x,&a,&da);
switch (n) {
case 1:
- if (a*a < 0.01588) return bsloww(-a,-da,x,n);
- else return bsloww1(-a,-da,x,n);
+ if (a*a < 0.01588) retval = bsloww(-a,-da,x,n);
+ else retval = bsloww1(-a,-da,x,n);
+ goto ret;
break;
case 3:
- if (a*a < 0.01588) return bsloww(a,da,x,n);
- else return bsloww1(a,da,x,n);
+ if (a*a < 0.01588) retval = bsloww(a,da,x,n);
+ else retval = bsloww1(a,da,x,n);
+ goto ret;
break;
case 0:
case 2:
- return bsloww2(a,da,x,n);
+ retval = bsloww2(a,da,x,n);
+ goto ret;
break;
}
@@ -592,10 +630,13 @@ __cos(double x)
else {
if (k == 0x7ff00000 && u.i[LOW_HALF] == 0)
__set_errno (EDOM);
- return x / x; /* |x| > 2^1024 */
+ retval = x / x; /* |x| > 2^1024 */
+ goto ret;
}
- return 0;
+ ret:
+ libc_feupdateenv (&env);
+ return retval;
}
/************************************************************************/
diff --git a/sysdeps/ieee754/dbl-64/s_tan.c b/sysdeps/ieee754/dbl-64/s_tan.c
index 962a4eba6b..2c26756ff2 100644
--- a/sysdeps/ieee754/dbl-64/s_tan.c
+++ b/sysdeps/ieee754/dbl-64/s_tan.c
@@ -39,6 +39,8 @@
#include "mpa.h"
#include "MathLib.h"
#include "math.h"
+#include "math_private.h"
+#include <fenv.h>
#ifndef SECTION
# define SECTION
@@ -66,21 +68,27 @@ tan(double x) {
mp_no mpy;
#endif
+ fenv_t env;
+ double retval;
+
int __branred(double, double *, double *);
int __mpranred(double, mp_no *, int);
+ libc_feholdexcept_setround (&env, FE_TONEAREST);
+
/* x=+-INF, x=NaN */
num.d = x; ux = num.i[HIGH_HALF];
if ((ux&0x7ff00000)==0x7ff00000) {
if ((ux&0x7fffffff)==0x7ff00000)
__set_errno (EDOM);
- return x-x;
+ retval = x-x;
+ goto ret;
}
w=(x<ZERO) ? -x : x;
/* (I) The case abs(x) <= 1.259e-8 */
- if (w<=g1.d) return x;
+ if (w<=g1.d) { retval = x; goto ret; }
/* (II) The case 1.259e-8 < abs(x) <= 0.0608 */
if (w<=g2.d) {
@@ -88,7 +96,7 @@ tan(double x) {
/* First stage */
x2 = x*x;
t2 = x*x2*(d3.d+x2*(d5.d+x2*(d7.d+x2*(d9.d+x2*d11.d))));
- if ((y=x+(t2-u1.d*t2)) == x+(t2+u1.d*t2)) return y;
+ if ((y=x+(t2-u1.d*t2)) == x+(t2+u1.d*t2)) { retval = y; goto ret; }
/* Second stage */
c1 = x2*(a15.d+x2*(a17.d+x2*(a19.d+x2*(a21.d+x2*(a23.d+x2*(a25.d+
@@ -108,8 +116,9 @@ tan(double x) {
MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
MUL2(x ,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
ADD2(x ,zero.d,c2,cc2,c1,cc1,t1,t2)
- if ((y=c1+(cc1-u2.d*c1)) == c1+(cc1+u2.d*c1)) return y;
- return tanMp(x);
+ if ((y=c1+(cc1-u2.d*c1)) == c1+(cc1+u2.d*c1)) { retval = y; goto ret; }
+ retval = tanMp(x);
+ goto ret;
}
/* (III) The case 0.0608 < abs(x) <= 0.787 */
@@ -120,10 +129,10 @@ tan(double x) {
z = w-xfg[i][0].d; z2 = z*z; s = (x<ZERO) ? MONE : ONE;
pz = z+z*z2*(e0.d+z2*e1.d);
fi = xfg[i][1].d; gi = xfg[i][2].d; t2 = pz*(gi+fi)/(gi-pz);
- if ((y=fi+(t2-fi*u3.d))==fi+(t2+fi*u3.d)) return (s*y);
+ if ((y=fi+(t2-fi*u3.d))==fi+(t2+fi*u3.d)) { retval = (s*y); goto ret; }
t3 = (t2<ZERO) ? -t2 : t2;
t4 = fi*ua3.d+t3*ub3.d;
- if ((y=fi+(t2-t4))==fi+(t2+t4)) return (s*y);
+ if ((y=fi+(t2-t4))==fi+(t2+t4)) { retval = (s*y); goto ret; }
/* Second stage */
ffi = xfg[i][3].d;
@@ -141,8 +150,9 @@ tan(double x) {
SUB2(one.d,zero.d,c3,cc3,c1,cc1,t1,t2)
DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c3+(cc3-u4.d*c3))==c3+(cc3+u4.d*c3)) return (s*y);
- return tanMp(x);
+ if ((y=c3+(cc3-u4.d*c3))==c3+(cc3+u4.d*c3)) { retval = (s*y); goto ret; }
+ retval = tanMp(x);
+ goto ret;
}
/* (---) The case 0.787 < abs(x) <= 25 */
@@ -160,7 +170,7 @@ tan(double x) {
else {ya= a; yya= da; sy= ONE;}
/* (IV),(V) The case 0.787 < abs(x) <= 25, abs(y) <= 1e-7 */
- if (ya<=gy1.d) return tanMp(x);
+ if (ya<=gy1.d) { retval = tanMp(x); goto ret; }
/* (VI) The case 0.787 < abs(x) <= 25, 1e-7 < abs(y) <= 0.0608 */
if (ya<=gy2.d) {
@@ -170,10 +180,10 @@ tan(double x) {
/* First stage -cot */
EADD(a,t2,b,db)
DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c+(dc-u6.d*c))==c+(dc+u6.d*c)) return (-y); }
+ if ((y=c+(dc-u6.d*c))==c+(dc+u6.d*c)) { retval = (-y); goto ret; } }
else {
/* First stage tan */
- if ((y=a+(t2-u5.d*a))==a+(t2+u5.d*a)) return y; }
+ if ((y=a+(t2-u5.d*a))==a+(t2+u5.d*a)) { retval = y; goto ret; } }
/* Second stage */
/* Range reduction by algorithm ii */
t = (x*hpinv.d + toint.d);
@@ -211,11 +221,12 @@ tan(double x) {
if (n) {
/* Second stage -cot */
DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c2+(cc2-u8.d*c2)) == c2+(cc2+u8.d*c2)) return (-y); }
+ if ((y=c2+(cc2-u8.d*c2)) == c2+(cc2+u8.d*c2)) { retval = (-y); goto ret; } }
else {
/* Second stage tan */
- if ((y=c1+(cc1-u7.d*c1)) == c1+(cc1+u7.d*c1)) return y; }
- return tanMp(x);
+ if ((y=c1+(cc1-u7.d*c1)) == c1+(cc1+u7.d*c1)) { retval = y; goto ret; } }
+ retval = tanMp(x);
+ goto ret;
}
/* (VII) The case 0.787 < abs(x) <= 25, 0.0608 < abs(y) <= 0.787 */
@@ -229,17 +240,17 @@ tan(double x) {
if (n) {
/* -cot */
t2 = pz*(fi+gi)/(fi+pz);
- if ((y=gi-(t2-gi*u10.d))==gi-(t2+gi*u10.d)) return (-sy*y);
+ if ((y=gi-(t2-gi*u10.d))==gi-(t2+gi*u10.d)) { retval = (-sy*y); goto ret; }
t3 = (t2<ZERO) ? -t2 : t2;
t4 = gi*ua10.d+t3*ub10.d;
- if ((y=gi-(t2-t4))==gi-(t2+t4)) return (-sy*y); }
+ if ((y=gi-(t2-t4))==gi-(t2+t4)) { retval = (-sy*y); goto ret; } }
else {
/* tan */
t2 = pz*(gi+fi)/(gi-pz);
- if ((y=fi+(t2-fi*u9.d))==fi+(t2+fi*u9.d)) return (sy*y);
+ if ((y=fi+(t2-fi*u9.d))==fi+(t2+fi*u9.d)) { retval = (sy*y); goto ret; }
t3 = (t2<ZERO) ? -t2 : t2;
t4 = fi*ua9.d+t3*ub9.d;
- if ((y=fi+(t2-t4))==fi+(t2+t4)) return (sy*y); }
+ if ((y=fi+(t2-t4))==fi+(t2+t4)) { retval = (sy*y); goto ret; } }
/* Second stage */
ffi = xfg[i][3].d;
@@ -260,13 +271,14 @@ tan(double x) {
if (n) {
/* -cot */
DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c3+(cc3-u12.d*c3))==c3+(cc3+u12.d*c3)) return (-sy*y); }
+ if ((y=c3+(cc3-u12.d*c3))==c3+(cc3+u12.d*c3)) { retval = (-sy*y); goto ret; } }
else {
/* tan */
DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c3+(cc3-u11.d*c3))==c3+(cc3+u11.d*c3)) return (sy*y); }
+ if ((y=c3+(cc3-u11.d*c3))==c3+(cc3+u11.d*c3)) { retval = (sy*y); goto ret; } }
- return tanMp(x);
+ retval = tanMp(x);
+ goto ret;
}
/* (---) The case 25 < abs(x) <= 1e8 */
@@ -288,7 +300,7 @@ tan(double x) {
else {ya= a; yya= da; sy= ONE;}
/* (+++) The case 25 < abs(x) <= 1e8, abs(y) <= 1e-7 */
- if (ya<=gy1.d) return tanMp(x);
+ if (ya<=gy1.d) { retval = tanMp(x); goto ret; }
/* (VIII) The case 25 < abs(x) <= 1e8, 1e-7 < abs(y) <= 0.0608 */
if (ya<=gy2.d) {
@@ -298,10 +310,10 @@ tan(double x) {
/* First stage -cot */
EADD(a,t2,b,db)
DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c+(dc-u14.d*c))==c+(dc+u14.d*c)) return (-y); }
+ if ((y=c+(dc-u14.d*c))==c+(dc+u14.d*c)) { retval = (-y); goto ret; } }
else {
/* First stage tan */
- if ((y=a+(t2-u13.d*a))==a+(t2+u13.d*a)) return y; }
+ if ((y=a+(t2-u13.d*a))==a+(t2+u13.d*a)) { retval = y; goto ret; } }
/* Second stage */
MUL2(a,da,a,da,x2,xx2,t1,t2,t3,t4,t5,t6,t7,t8)
@@ -325,11 +337,12 @@ tan(double x) {
if (n) {
/* Second stage -cot */
DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c2+(cc2-u16.d*c2)) == c2+(cc2+u16.d*c2)) return (-y); }
+ if ((y=c2+(cc2-u16.d*c2)) == c2+(cc2+u16.d*c2)) { retval = (-y); goto ret; } }
else {
/* Second stage tan */
- if ((y=c1+(cc1-u15.d*c1)) == c1+(cc1+u15.d*c1)) return (y); }
- return tanMp(x);
+ if ((y=c1+(cc1-u15.d*c1)) == c1+(cc1+u15.d*c1)) { retval = (y); goto ret; } }
+ retval = tanMp(x);
+ goto ret;
}
/* (IX) The case 25 < abs(x) <= 1e8, 0.0608 < abs(y) <= 0.787 */
@@ -342,17 +355,17 @@ tan(double x) {
if (n) {
/* -cot */
t2 = pz*(fi+gi)/(fi+pz);
- if ((y=gi-(t2-gi*u18.d))==gi-(t2+gi*u18.d)) return (-sy*y);
+ if ((y=gi-(t2-gi*u18.d))==gi-(t2+gi*u18.d)) { retval = (-sy*y); goto ret; }
t3 = (t2<ZERO) ? -t2 : t2;
t4 = gi*ua18.d+t3*ub18.d;
- if ((y=gi-(t2-t4))==gi-(t2+t4)) return (-sy*y); }
+ if ((y=gi-(t2-t4))==gi-(t2+t4)) { retval = (-sy*y); goto ret; } }
else {
/* tan */
t2 = pz*(gi+fi)/(gi-pz);
- if ((y=fi+(t2-fi*u17.d))==fi+(t2+fi*u17.d)) return (sy*y);
+ if ((y=fi+(t2-fi*u17.d))==fi+(t2+fi*u17.d)) { retval = (sy*y); goto ret; }
t3 = (t2<ZERO) ? -t2 : t2;
t4 = fi*ua17.d+t3*ub17.d;
- if ((y=fi+(t2-t4))==fi+(t2+t4)) return (sy*y); }
+ if ((y=fi+(t2-t4))==fi+(t2+t4)) { retval = (sy*y); goto ret; } }
/* Second stage */
ffi = xfg[i][3].d;
@@ -373,12 +386,13 @@ tan(double x) {
if (n) {
/* -cot */
DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c3+(cc3-u20.d*c3))==c3+(cc3+u20.d*c3)) return (-sy*y); }
+ if ((y=c3+(cc3-u20.d*c3))==c3+(cc3+u20.d*c3)) { retval = (-sy*y); goto ret; } }
else {
/* tan */
DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c3+(cc3-u19.d*c3))==c3+(cc3+u19.d*c3)) return (sy*y); }
- return tanMp(x);
+ if ((y=c3+(cc3-u19.d*c3))==c3+(cc3+u19.d*c3)) { retval = (sy*y); goto ret; } }
+ retval = tanMp(x);
+ goto ret;
}
/* (---) The case 1e8 < abs(x) < 2**1024 */
@@ -389,7 +403,7 @@ tan(double x) {
else {ya= a; yya= da; sy= ONE;}
/* (+++) The case 1e8 < abs(x) < 2**1024, abs(y) <= 1e-7 */
- if (ya<=gy1.d) return tanMp(x);
+ if (ya<=gy1.d) { retval = tanMp(x); goto ret; }
/* (X) The case 1e8 < abs(x) < 2**1024, 1e-7 < abs(y) <= 0.0608 */
if (ya<=gy2.d) {
@@ -399,10 +413,10 @@ tan(double x) {
/* First stage -cot */
EADD(a,t2,b,db)
DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c+(dc-u22.d*c))==c+(dc+u22.d*c)) return (-y); }
+ if ((y=c+(dc-u22.d*c))==c+(dc+u22.d*c)) { retval = (-y); goto ret; } }
else {
/* First stage tan */
- if ((y=a+(t2-u21.d*a))==a+(t2+u21.d*a)) return y; }
+ if ((y=a+(t2-u21.d*a))==a+(t2+u21.d*a)) { retval = y; goto ret; } }
/* Second stage */
/* Reduction by algorithm iv */
@@ -431,11 +445,12 @@ tan(double x) {
if (n) {
/* Second stage -cot */
DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c2+(cc2-u24.d*c2)) == c2+(cc2+u24.d*c2)) return (-y); }
+ if ((y=c2+(cc2-u24.d*c2)) == c2+(cc2+u24.d*c2)) { retval = (-y); goto ret; } }
else {
/* Second stage tan */
- if ((y=c1+(cc1-u23.d*c1)) == c1+(cc1+u23.d*c1)) return y; }
- return tanMp(x);
+ if ((y=c1+(cc1-u23.d*c1)) == c1+(cc1+u23.d*c1)) { retval = y; goto ret; } }
+ retval = tanMp(x);
+ goto ret;
}
/* (XI) The case 1e8 < abs(x) < 2**1024, 0.0608 < abs(y) <= 0.787 */
@@ -448,17 +463,17 @@ tan(double x) {
if (n) {
/* -cot */
t2 = pz*(fi+gi)/(fi+pz);
- if ((y=gi-(t2-gi*u26.d))==gi-(t2+gi*u26.d)) return (-sy*y);
+ if ((y=gi-(t2-gi*u26.d))==gi-(t2+gi*u26.d)) { retval = (-sy*y); goto ret; }
t3 = (t2<ZERO) ? -t2 : t2;
t4 = gi*ua26.d+t3*ub26.d;
- if ((y=gi-(t2-t4))==gi-(t2+t4)) return (-sy*y); }
+ if ((y=gi-(t2-t4))==gi-(t2+t4)) { retval = (-sy*y); goto ret; } }
else {
/* tan */
t2 = pz*(gi+fi)/(gi-pz);
- if ((y=fi+(t2-fi*u25.d))==fi+(t2+fi*u25.d)) return (sy*y);
+ if ((y=fi+(t2-fi*u25.d))==fi+(t2+fi*u25.d)) { retval = (sy*y); goto ret; }
t3 = (t2<ZERO) ? -t2 : t2;
t4 = fi*ua25.d+t3*ub25.d;
- if ((y=fi+(t2-t4))==fi+(t2+t4)) return (sy*y); }
+ if ((y=fi+(t2-t4))==fi+(t2+t4)) { retval = (sy*y); goto ret; } }
/* Second stage */
ffi = xfg[i][3].d;
@@ -479,14 +494,18 @@ tan(double x) {
if (n) {
/* -cot */
DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c3+(cc3-u28.d*c3))==c3+(cc3+u28.d*c3)) return (-sy*y); }
+ if ((y=c3+(cc3-u28.d*c3))==c3+(cc3+u28.d*c3)) { retval = (-sy*y); goto ret; } }
else {
/* tan */
DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
- if ((y=c3+(cc3-u27.d*c3))==c3+(cc3+u27.d*c3)) return (sy*y); }
- return tanMp(x);
-}
+ if ((y=c3+(cc3-u27.d*c3))==c3+(cc3+u27.d*c3)) { retval = (sy*y); goto ret; } }
+ retval = tanMp(x);
+ goto ret;
+ ret:
+ libc_feupdateenv (&env);
+ return retval;
+}
/* multiple precision stage */
/* Convert x to multi precision number,compute tan(x) by mptan() routine */