diff options
author | Thomas Schwinge <thomas@codesourcery.com> | 2013-12-20 09:32:04 +0100 |
---|---|---|
committer | Thomas Schwinge <thomas@codesourcery.com> | 2013-12-20 09:32:04 +0100 |
commit | 1ff35137add0e9637df9e3fcc21133674188c8c4 (patch) | |
tree | 8adaab857154e5d87bf4bcaa60fa71517b9cb6a2 /sysdeps/ieee754 | |
parent | c3e519d5360f96ecd7afe32c34e74483852d278d (diff) | |
parent | ddd183dfa34297ea2660882ba01f9f9cbb59f646 (diff) |
Merge commit 'refs/top-bases/t/hurdsig-SA_SIGINFO' into t/hurdsig-SA_SIGINFO
Diffstat (limited to 'sysdeps/ieee754')
161 files changed, 4971 insertions, 5314 deletions
diff --git a/sysdeps/ieee754/dbl-64/Makefile b/sysdeps/ieee754/dbl-64/Makefile index 1a7b31158d..35f545ff8e 100644 --- a/sysdeps/ieee754/dbl-64/Makefile +++ b/sysdeps/ieee754/dbl-64/Makefile @@ -1,4 +1,5 @@ ifeq ($(subdir),math) # branred depends on precise IEEE double rounding CFLAGS-branred.c = $(config-cflags-nofma) +CFLAGS-e_sqrt.c = $(config-cflags-nofma) endif diff --git a/sysdeps/ieee754/dbl-64/MathLib.h b/sysdeps/ieee754/dbl-64/MathLib.h index 23f71980bb..cf56606e36 100644 --- a/sysdeps/ieee754/dbl-64/MathLib.h +++ b/sysdeps/ieee754/dbl-64/MathLib.h @@ -33,14 +33,14 @@ /* It returns the original status of these modes. */ /* See further explanations of usage in DPChange.h */ /********************************************************************/ -unsigned short Init_Lib(void); +unsigned short Init_Lib (void); /********************************************************************/ /* Function that changes the precision and rounding modes to the */ /* specified by the argument received. See further explanations in */ /* DPChange.h */ /********************************************************************/ -void Exit_Lib(unsigned short); +void Exit_Lib (unsigned short); /* The asin() function calculates the arc sine of its argument. */ @@ -48,7 +48,7 @@ void Exit_Lib(unsigned short); /* (between -PI/2 and PI/2). */ /* If the argument is greater than 1 or less than -1 it returns */ /* a NaN. */ -double uasin(double ); +double uasin (double); /* The acos() function calculates the arc cosine of its argument. */ @@ -56,47 +56,45 @@ double uasin(double ); /* (between -PI/2 and PI/2). */ /* If the argument is greater than 1 or less than -1 it returns */ /* a NaN. */ -double uacos(double ); +double uacos (double); /* The atan() function calculates the arctanget of its argument. */ /* The function returns the arc tangent in radians */ /* (between -PI/2 and PI/2). */ -double uatan(double ); +double uatan (double); /* The uatan2() function calculates the arc tangent of the two arguments x */ /* and y (x is the right argument and y is the left one).The signs of both */ /* arguments are used to determine the quadrant of the result. */ /* The function returns the result in radians, which is between -PI and PI */ -double uatan2(double ,double ); +double uatan2 (double, double); /* Compute log(x). The base of log is e (natural logarithm) */ -double ulog(double ); +double ulog (double); /* Compute e raised to the power of argument x. */ -double uexp(double ); +double uexp (double); /* Compute sin(x). The argument x is assumed to be given in radians.*/ -double usin(double ); +double usin (double); /* Compute cos(x). The argument x is assumed to be given in radians.*/ -double ucos(double ); +double ucos (double); /* Compute tan(x). The argument x is assumed to be given in radians.*/ -double utan(double ); +double utan (double); /* Compute the square root of non-negative argument x. */ /* If x is negative the returned value is NaN. */ -double usqrt(double ); +double usqrt (double); /* Compute x raised to the power of y, where x is the left argument */ /* and y is the right argument. The function returns a NaN if x<0. */ /* If x equals zero it returns -inf */ -double upow(double , double ); +double upow (double, double); /* Computing x mod y, where x is the left argument and y is the */ /* right one. */ -double uremainder(double , double ); - - +double uremainder (double, double); #endif diff --git a/sysdeps/ieee754/dbl-64/dbl2mpn.c b/sysdeps/ieee754/dbl-64/dbl2mpn.c index f2294de5aa..087d64377b 100644 --- a/sysdeps/ieee754/dbl-64/dbl2mpn.c +++ b/sysdeps/ieee754/dbl-64/dbl2mpn.c @@ -40,14 +40,14 @@ __mpn_extract_double (mp_ptr res_ptr, mp_size_t size, #if BITS_PER_MP_LIMB == 32 res_ptr[0] = u.ieee.mantissa1; /* Low-order 32 bits of fraction. */ res_ptr[1] = u.ieee.mantissa0; /* High-order 20 bits. */ - #define N 2 + # define N 2 #elif BITS_PER_MP_LIMB == 64 /* Hopefully the compiler will combine the two bitfield extracts and this composition into just the original quadword extract. */ res_ptr[0] = ((mp_limb_t) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; - #define N 1 + # define N 1 #else - #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" + # error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" #endif /* The format does not fill the last limb. There are some zeros. */ #define NUM_LEADING_ZEROS (BITS_PER_MP_LIMB \ @@ -73,7 +73,7 @@ __mpn_extract_double (mp_ptr res_ptr, mp_size_t size, #if N == 2 res_ptr[N - 1] = res_ptr[1] << cnt | (N - 1) - * (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt)); + * (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt)); res_ptr[0] <<= cnt; #else res_ptr[N - 1] <<= cnt; diff --git a/sysdeps/ieee754/dbl-64/dla.h b/sysdeps/ieee754/dbl-64/dla.h index b09f00ec75..6666982bfa 100644 --- a/sysdeps/ieee754/dbl-64/dla.h +++ b/sysdeps/ieee754/dbl-64/dla.h @@ -61,13 +61,13 @@ /* storage variables of type double. */ #ifdef DLA_FMS -# define EMULV(x,y,z,zz,p,hx,tx,hy,ty) \ - z=x*y; zz=DLA_FMS(x,y,z); +# define EMULV(x, y, z, zz, p, hx, tx, hy, ty) \ + z = x * y; zz = DLA_FMS (x, y, z); #else -# define EMULV(x,y,z,zz,p,hx,tx,hy,ty) \ - p=CN*(x); hx=((x)-p)+p; tx=(x)-hx; \ - p=CN*(y); hy=((y)-p)+p; ty=(y)-hy; \ - z=(x)*(y); zz=(((hx*hy-z)+hx*ty)+tx*hy)+tx*ty; +# define EMULV(x, y, z, zz, p, hx, tx, hy, ty) \ + p = CN * (x); hx = ((x) - p) + p; tx = (x) - hx; \ + p = CN * (y); hy = ((y) - p) + p; ty = (y) - hy; \ + z = (x) * (y); zz = (((hx * hy - z) + hx * ty) + tx * hy) + tx * ty; #endif @@ -93,11 +93,11 @@ /* are assumed to be double-length numbers. r,s are temporary */ /* storage variables of type double. */ -#define ADD2(x,xx,y,yy,z,zz,r,s) \ - r=(x)+(y); s=(ABS(x)>ABS(y)) ? \ - (((((x)-r)+(y))+(yy))+(xx)) : \ - (((((y)-r)+(x))+(xx))+(yy)); \ - z=r+s; zz=(r-z)+s; +#define ADD2(x, xx, y, yy, z, zz, r, s) \ + r = (x) + (y); s = (ABS (x) > ABS (y)) ? \ + (((((x) - r) + (y)) + (yy)) + (xx)) : \ + (((((y) - r) + (x)) + (xx)) + (yy)); \ + z = r + s; zz = (r - z) + s; /* Double-length subtraction, Dekker. The macro produces a double-length */ @@ -106,11 +106,11 @@ /* are assumed to be double-length numbers. r,s are temporary */ /* storage variables of type double. */ -#define SUB2(x,xx,y,yy,z,zz,r,s) \ - r=(x)-(y); s=(ABS(x)>ABS(y)) ? \ - (((((x)-r)-(y))-(yy))+(xx)) : \ - ((((x)-((y)+r))+(xx))-(yy)); \ - z=r+s; zz=(r-z)+s; +#define SUB2(x, xx, y, yy, z, zz, r, s) \ + r = (x) - (y); s = (ABS (x) > ABS (y)) ? \ + (((((x) - r) - (y)) - (yy)) + (xx)) : \ + ((((x) - ((y) + r)) + (xx)) - (yy)); \ + z = r + s; zz = (r - z) + s; /* Double-length multiplication, Dekker. The macro produces a double-length */ @@ -119,9 +119,9 @@ /* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc are */ /* temporary storage variables of type double. */ -#define MUL2(x,xx,y,yy,z,zz,p,hx,tx,hy,ty,q,c,cc) \ - MUL12(x,y,c,cc,p,hx,tx,hy,ty,q) \ - cc=((x)*(yy)+(xx)*(y))+cc; z=c+cc; zz=(c-z)+cc; +#define MUL2(x, xx, y, yy, z, zz, p, hx, tx, hy, ty, q, c, cc) \ + MUL12 (x, y, c, cc, p, hx, tx, hy, ty, q) \ + cc = ((x) * (yy) + (xx) * (y)) + cc; z = c + cc; zz = (c - z) + cc; /* Double-length division, Dekker. The macro produces a double-length */ @@ -142,18 +142,18 @@ /* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */ /* are temporary storage variables of type double. */ -#define ADD2A(x,xx,y,yy,z,zz,r,rr,s,ss,u,uu,w) \ - r=(x)+(y); \ - if (ABS(x)>ABS(y)) { rr=((x)-r)+(y); s=(rr+(yy))+(xx); } \ - else { rr=((y)-r)+(x); s=(rr+(xx))+(yy); } \ - if (rr!=0.0) { \ - z=r+s; zz=(r-z)+s; } \ - else { \ - ss=(ABS(xx)>ABS(yy)) ? (((xx)-s)+(yy)) : (((yy)-s)+(xx)); \ - u=r+s; \ - uu=(ABS(r)>ABS(s)) ? ((r-u)+s) : ((s-u)+r) ; \ - w=uu+ss; z=u+w; \ - zz=(ABS(u)>ABS(w)) ? ((u-z)+w) : ((w-z)+u) ; } +#define ADD2A(x, xx, y, yy, z, zz, r, rr, s, ss, u, uu, w) \ + r = (x) + (y); \ + if (ABS (x) > ABS (y)) { rr = ((x) - r) + (y); s = (rr + (yy)) + (xx); } \ + else { rr = ((y) - r) + (x); s = (rr + (xx)) + (yy); } \ + if (rr != 0.0) { \ + z = r + s; zz = (r - z) + s; } \ + else { \ + ss = (ABS (xx) > ABS (yy)) ? (((xx) - s) + (yy)) : (((yy) - s) + (xx));\ + u = r + s; \ + uu = (ABS (r) > ABS (s)) ? ((r - u) + s) : ((s - u) + r); \ + w = uu + ss; z = u + w; \ + zz = (ABS (u) > ABS (w)) ? ((u - z) + w) : ((w - z) + u); } /* Double-length subtraction, slower but more accurate than SUB2. */ @@ -163,15 +163,15 @@ /* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */ /* are temporary storage variables of type double. */ -#define SUB2A(x,xx,y,yy,z,zz,r,rr,s,ss,u,uu,w) \ - r=(x)-(y); \ - if (ABS(x)>ABS(y)) { rr=((x)-r)-(y); s=(rr-(yy))+(xx); } \ - else { rr=(x)-((y)+r); s=(rr+(xx))-(yy); } \ - if (rr!=0.0) { \ - z=r+s; zz=(r-z)+s; } \ - else { \ - ss=(ABS(xx)>ABS(yy)) ? (((xx)-s)-(yy)) : ((xx)-((yy)+s)); \ - u=r+s; \ - uu=(ABS(r)>ABS(s)) ? ((r-u)+s) : ((s-u)+r) ; \ - w=uu+ss; z=u+w; \ - zz=(ABS(u)>ABS(w)) ? ((u-z)+w) : ((w-z)+u) ; } +#define SUB2A(x, xx, y, yy, z, zz, r, rr, s, ss, u, uu, w) \ + r = (x) - (y); \ + if (ABS (x) > ABS (y)) { rr = ((x) - r) - (y); s = (rr - (yy)) + (xx); } \ + else { rr = (x) - ((y) + r); s = (rr + (xx)) - (yy); } \ + if (rr != 0.0) { \ + z = r + s; zz = (r - z) + s; } \ + else { \ + ss = (ABS (xx) > ABS (yy)) ? (((xx) - s) - (yy)) : ((xx) - ((yy) + s)); \ + u = r + s; \ + uu = (ABS (r) > ABS (s)) ? ((r - u) + s) : ((s - u) + r); \ + w = uu + ss; z = u + w; \ + zz = (ABS (u) > ABS (w)) ? ((u - z) + w) : ((w - z) + u); } diff --git a/sysdeps/ieee754/dbl-64/dosincos.c b/sysdeps/ieee754/dbl-64/dosincos.c index 00726285a9..e1c8836b72 100644 --- a/sysdeps/ieee754/dbl-64/dosincos.c +++ b/sysdeps/ieee754/dbl-64/dosincos.c @@ -57,49 +57,52 @@ extern const union void SECTION -__dubsin(double x, double dx, double v[]) { - double r,s,c,cc,d,dd,d2,dd2,e,ee, - sn,ssn,cs,ccs,ds,dss,dc,dcc; +__dubsin (double x, double dx, double v[]) +{ + double r, s, c, cc, d, dd, d2, dd2, e, ee, + sn, ssn, cs, ccs, ds, dss, dc, dcc; #ifndef DLA_FMS - double p,hx,tx,hy,ty,q; + double p, hx, tx, hy, ty, q; #endif mynumber u; int4 k; - u.x=x+big.x; - k = u.i[LOW_HALF]<<2; - x=x-(u.x-big.x); - d=x+dx; - dd=(x-d)+dx; - /* sin(x+dx)=sin(Xi+t)=sin(Xi)*cos(t) + cos(Xi)sin(t) where t ->0 */ - MUL2(d,dd,d,dd,d2,dd2,p,hx,tx,hy,ty,q,c,cc); - sn=__sincostab.x[k]; /* */ - ssn=__sincostab.x[k+1]; /* sin(Xi) and cos(Xi) */ - cs=__sincostab.x[k+2]; /* */ - ccs=__sincostab.x[k+3]; /* */ - MUL2(d2,dd2,s7.x,ss7.x,ds,dss,p,hx,tx,hy,ty,q,c,cc); /* Taylor */ - ADD2(ds,dss,s5.x,ss5.x,ds,dss,r,s); - MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); /* series */ - ADD2(ds,dss,s3.x,ss3.x,ds,dss,r,s); - MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); /* for sin */ - MUL2(d,dd,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); - ADD2(ds,dss,d,dd,ds,dss,r,s); /* ds=sin(t) */ - - MUL2(d2,dd2,c8.x,cc8.x,dc,dcc,p,hx,tx,hy,ty,q,c,cc); ;/* Taylor */ - ADD2(dc,dcc,c6.x,cc6.x,dc,dcc,r,s); - MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); /* series */ - ADD2(dc,dcc,c4.x,cc4.x,dc,dcc,r,s); - MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); /* for cos */ - ADD2(dc,dcc,c2.x,cc2.x,dc,dcc,r,s); - MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); /* dc=cos(t) */ - - MUL2(cs,ccs,ds,dss,e,ee,p,hx,tx,hy,ty,q,c,cc); - MUL2(dc,dcc,sn,ssn,dc,dcc,p,hx,tx,hy,ty,q,c,cc); - SUB2(e,ee,dc,dcc,e,ee,r,s); - ADD2(e,ee,sn,ssn,e,ee,r,s); /* e+ee=sin(x+dx) */ - - v[0]=e; - v[1]=ee; + u.x = x + big.x; + k = u.i[LOW_HALF] << 2; + x = x - (u.x - big.x); + d = x + dx; + dd = (x - d) + dx; + /* sin(x+dx)=sin(Xi+t)=sin(Xi)*cos(t) + cos(Xi)sin(t) where t ->0 */ + MUL2 (d, dd, d, dd, d2, dd2, p, hx, tx, hy, ty, q, c, cc); + sn = __sincostab.x[k]; /* */ + ssn = __sincostab.x[k + 1]; /* sin(Xi) and cos(Xi) */ + cs = __sincostab.x[k + 2]; /* */ + ccs = __sincostab.x[k + 3]; /* */ + /* Taylor series for sin ds=sin(t) */ + MUL2 (d2, dd2, s7.x, ss7.x, ds, dss, p, hx, tx, hy, ty, q, c, cc); + ADD2 (ds, dss, s5.x, ss5.x, ds, dss, r, s); + MUL2 (d2, dd2, ds, dss, ds, dss, p, hx, tx, hy, ty, q, c, cc); + ADD2 (ds, dss, s3.x, ss3.x, ds, dss, r, s); + MUL2 (d2, dd2, ds, dss, ds, dss, p, hx, tx, hy, ty, q, c, cc); + MUL2 (d, dd, ds, dss, ds, dss, p, hx, tx, hy, ty, q, c, cc); + ADD2 (ds, dss, d, dd, ds, dss, r, s); + + /* Taylor series for cos dc=cos(t) */ + MUL2 (d2, dd2, c8.x, cc8.x, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + ADD2 (dc, dcc, c6.x, cc6.x, dc, dcc, r, s); + MUL2 (d2, dd2, dc, dcc, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + ADD2 (dc, dcc, c4.x, cc4.x, dc, dcc, r, s); + MUL2 (d2, dd2, dc, dcc, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + ADD2 (dc, dcc, c2.x, cc2.x, dc, dcc, r, s); + MUL2 (d2, dd2, dc, dcc, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + + MUL2 (cs, ccs, ds, dss, e, ee, p, hx, tx, hy, ty, q, c, cc); + MUL2 (dc, dcc, sn, ssn, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + SUB2 (e, ee, dc, dcc, e, ee, r, s); + ADD2 (e, ee, sn, ssn, e, ee, r, s); /* e+ee=sin(x+dx) */ + + v[0] = e; + v[1] = ee; } /**********************************************************************/ /* Routine receive Double-Length number (x+dx) and computes cos(x+dx) */ @@ -110,64 +113,65 @@ __dubsin(double x, double dx, double v[]) { void SECTION -__dubcos(double x, double dx, double v[]) { - double r,s,c,cc,d,dd,d2,dd2,e,ee, - sn,ssn,cs,ccs,ds,dss,dc,dcc; +__dubcos (double x, double dx, double v[]) +{ + double r, s, c, cc, d, dd, d2, dd2, e, ee, + sn, ssn, cs, ccs, ds, dss, dc, dcc; #ifndef DLA_FMS - double p,hx,tx,hy,ty,q; + double p, hx, tx, hy, ty, q; #endif mynumber u; int4 k; - u.x=x+big.x; - k = u.i[LOW_HALF]<<2; - x=x-(u.x-big.x); - d=x+dx; - dd=(x-d)+dx; /* cos(x+dx)=cos(Xi+t)=cos(Xi)cos(t) - sin(Xi)sin(t) */ - MUL2(d,dd,d,dd,d2,dd2,p,hx,tx,hy,ty,q,c,cc); - sn=__sincostab.x[k]; /* */ - ssn=__sincostab.x[k+1]; /* sin(Xi) and cos(Xi) */ - cs=__sincostab.x[k+2]; /* */ - ccs=__sincostab.x[k+3]; /* */ - MUL2(d2,dd2,s7.x,ss7.x,ds,dss,p,hx,tx,hy,ty,q,c,cc); - ADD2(ds,dss,s5.x,ss5.x,ds,dss,r,s); - MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); - ADD2(ds,dss,s3.x,ss3.x,ds,dss,r,s); - MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); - MUL2(d,dd,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); - ADD2(ds,dss,d,dd,ds,dss,r,s); - - MUL2(d2,dd2,c8.x,cc8.x,dc,dcc,p,hx,tx,hy,ty,q,c,cc); - ADD2(dc,dcc,c6.x,cc6.x,dc,dcc,r,s); - MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); - ADD2(dc,dcc,c4.x,cc4.x,dc,dcc,r,s); - MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); - ADD2(dc,dcc,c2.x,cc2.x,dc,dcc,r,s); - MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); - - MUL2(cs,ccs,ds,dss,e,ee,p,hx,tx,hy,ty,q,c,cc); - MUL2(dc,dcc,sn,ssn,dc,dcc,p,hx,tx,hy,ty,q,c,cc); - - MUL2(d2,dd2,s7.x,ss7.x,ds,dss,p,hx,tx,hy,ty,q,c,cc); - ADD2(ds,dss,s5.x,ss5.x,ds,dss,r,s); - MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); - ADD2(ds,dss,s3.x,ss3.x,ds,dss,r,s); - MUL2(d2,dd2,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); - MUL2(d,dd,ds,dss,ds,dss,p,hx,tx,hy,ty,q,c,cc); - ADD2(ds,dss,d,dd,ds,dss,r,s); - MUL2(d2,dd2,c8.x,cc8.x,dc,dcc,p,hx,tx,hy,ty,q,c,cc); - ADD2(dc,dcc,c6.x,cc6.x,dc,dcc,r,s); - MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); - ADD2(dc,dcc,c4.x,cc4.x,dc,dcc,r,s); - MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); - ADD2(dc,dcc,c2.x,cc2.x,dc,dcc,r,s); - MUL2(d2,dd2,dc,dcc,dc,dcc,p,hx,tx,hy,ty,q,c,cc); - MUL2(sn,ssn,ds,dss,e,ee,p,hx,tx,hy,ty,q,c,cc); - MUL2(dc,dcc,cs,ccs,dc,dcc,p,hx,tx,hy,ty,q,c,cc); - ADD2(e,ee,dc,dcc,e,ee,r,s); - SUB2(cs,ccs,e,ee,e,ee,r,s); - - v[0]=e; - v[1]=ee; + u.x = x + big.x; + k = u.i[LOW_HALF] << 2; + x = x - (u.x - big.x); + d = x + dx; + dd = (x - d) + dx; /* cos(x+dx)=cos(Xi+t)=cos(Xi)cos(t) - sin(Xi)sin(t) */ + MUL2 (d, dd, d, dd, d2, dd2, p, hx, tx, hy, ty, q, c, cc); + sn = __sincostab.x[k]; /* */ + ssn = __sincostab.x[k + 1]; /* sin(Xi) and cos(Xi) */ + cs = __sincostab.x[k + 2]; /* */ + ccs = __sincostab.x[k + 3]; /* */ + MUL2 (d2, dd2, s7.x, ss7.x, ds, dss, p, hx, tx, hy, ty, q, c, cc); + ADD2 (ds, dss, s5.x, ss5.x, ds, dss, r, s); + MUL2 (d2, dd2, ds, dss, ds, dss, p, hx, tx, hy, ty, q, c, cc); + ADD2 (ds, dss, s3.x, ss3.x, ds, dss, r, s); + MUL2 (d2, dd2, ds, dss, ds, dss, p, hx, tx, hy, ty, q, c, cc); + MUL2 (d, dd, ds, dss, ds, dss, p, hx, tx, hy, ty, q, c, cc); + ADD2 (ds, dss, d, dd, ds, dss, r, s); + + MUL2 (d2, dd2, c8.x, cc8.x, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + ADD2 (dc, dcc, c6.x, cc6.x, dc, dcc, r, s); + MUL2 (d2, dd2, dc, dcc, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + ADD2 (dc, dcc, c4.x, cc4.x, dc, dcc, r, s); + MUL2 (d2, dd2, dc, dcc, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + ADD2 (dc, dcc, c2.x, cc2.x, dc, dcc, r, s); + MUL2 (d2, dd2, dc, dcc, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + + MUL2 (cs, ccs, ds, dss, e, ee, p, hx, tx, hy, ty, q, c, cc); + MUL2 (dc, dcc, sn, ssn, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + + MUL2 (d2, dd2, s7.x, ss7.x, ds, dss, p, hx, tx, hy, ty, q, c, cc); + ADD2 (ds, dss, s5.x, ss5.x, ds, dss, r, s); + MUL2 (d2, dd2, ds, dss, ds, dss, p, hx, tx, hy, ty, q, c, cc); + ADD2 (ds, dss, s3.x, ss3.x, ds, dss, r, s); + MUL2 (d2, dd2, ds, dss, ds, dss, p, hx, tx, hy, ty, q, c, cc); + MUL2 (d, dd, ds, dss, ds, dss, p, hx, tx, hy, ty, q, c, cc); + ADD2 (ds, dss, d, dd, ds, dss, r, s); + MUL2 (d2, dd2, c8.x, cc8.x, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + ADD2 (dc, dcc, c6.x, cc6.x, dc, dcc, r, s); + MUL2 (d2, dd2, dc, dcc, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + ADD2 (dc, dcc, c4.x, cc4.x, dc, dcc, r, s); + MUL2 (d2, dd2, dc, dcc, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + ADD2 (dc, dcc, c2.x, cc2.x, dc, dcc, r, s); + MUL2 (d2, dd2, dc, dcc, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + MUL2 (sn, ssn, ds, dss, e, ee, p, hx, tx, hy, ty, q, c, cc); + MUL2 (dc, dcc, cs, ccs, dc, dcc, p, hx, tx, hy, ty, q, c, cc); + ADD2 (e, ee, dc, dcc, e, ee, r, s); + SUB2 (cs, ccs, e, ee, e, ee, r, s); + + v[0] = e; + v[1] = ee; } /**********************************************************************/ /* Routine receive Double-Length number (x+dx) and computes cos(x+dx) */ @@ -175,29 +179,45 @@ __dubcos(double x, double dx, double v[]) { /**********************************************************************/ void SECTION -__docos(double x, double dx, double v[]) { - double y,yy,p,w[2]; - if (x>0) {y=x; yy=dx;} - else {y=-x; yy=-dx;} - if (y<0.5*hp0.x) /* y< PI/4 */ - {__dubcos(y,yy,w); v[0]=w[0]; v[1]=w[1];} - else if (y<1.5*hp0.x) { /* y< 3/4 * PI */ - p=hp0.x-y; /* p = PI/2 - y */ - yy=hp1.x-yy; - y=p+yy; - yy=(p-y)+yy; - if (y>0) {__dubsin(y,yy,w); v[0]=w[0]; v[1]=w[1];} - /* cos(x) = sin ( 90 - x ) */ - else {__dubsin(-y,-yy,w); v[0]=-w[0]; v[1]=-w[1]; - } - } - else { /* y>= 3/4 * PI */ - p=2.0*hp0.x-y; /* p = PI- y */ - yy=2.0*hp1.x-yy; - y=p+yy; - yy=(p-y)+yy; - __dubcos(y,yy,w); - v[0]=-w[0]; - v[1]=-w[1]; - } +__docos (double x, double dx, double v[]) +{ + double y, yy, p, w[2]; + if (x > 0) + { + y = x; yy = dx; + } + else + { + y = -x; yy = -dx; + } + if (y < 0.5 * hp0.x) /* y< PI/4 */ + { + __dubcos (y, yy, w); v[0] = w[0]; v[1] = w[1]; + } + else if (y < 1.5 * hp0.x) /* y< 3/4 * PI */ + { + p = hp0.x - y; /* p = PI/2 - y */ + yy = hp1.x - yy; + y = p + yy; + yy = (p - y) + yy; + if (y > 0) + { + __dubsin (y, yy, w); v[0] = w[0]; v[1] = w[1]; + } + /* cos(x) = sin ( 90 - x ) */ + else + { + __dubsin (-y, -yy, w); v[0] = -w[0]; v[1] = -w[1]; + } + } + else /* y>= 3/4 * PI */ + { + p = 2.0 * hp0.x - y; /* p = PI- y */ + yy = 2.0 * hp1.x - yy; + y = p + yy; + yy = (p - y) + yy; + __dubcos (y, yy, w); + v[0] = -w[0]; + v[1] = -w[1]; + } } diff --git a/sysdeps/ieee754/dbl-64/e_acosh.c b/sysdeps/ieee754/dbl-64/e_acosh.c index b24a6f6459..c1f3590f75 100644 --- a/sysdeps/ieee754/dbl-64/e_acosh.c +++ b/sysdeps/ieee754/dbl-64/e_acosh.c @@ -28,31 +28,42 @@ #include <math_private.h> static const double -one = 1.0, -ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */ + one = 1.0, + ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */ double -__ieee754_acosh(double x) +__ieee754_acosh (double x) { - double t; - int32_t hx; - u_int32_t lx; - EXTRACT_WORDS(hx,lx,x); - if(hx<0x3ff00000) { /* x < 1 */ - return (x-x)/(x-x); - } else if(hx >=0x41b00000) { /* x > 2**28 */ - if(hx >=0x7ff00000) { /* x is inf of NaN */ - return x+x; - } else - return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */ - } else if(((hx-0x3ff00000)|lx)==0) { - return 0.0; /* acosh(1) = 0 */ - } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ - t=x*x; - return __ieee754_log(2.0*x-one/(x+__ieee754_sqrt(t-one))); - } else { /* 1<x<2 */ - t = x-one; - return __log1p(t+__ieee754_sqrt(2.0*t+t*t)); + double t; + int32_t hx; + u_int32_t lx; + EXTRACT_WORDS (hx, lx, x); + if (hx < 0x3ff00000) /* x < 1 */ + { + return (x - x) / (x - x); + } + else if (hx >= 0x41b00000) /* x > 2**28 */ + { + if (hx >= 0x7ff00000) /* x is inf of NaN */ + { + return x + x; } + else + return __ieee754_log (x) + ln2; /* acosh(huge)=log(2x) */ + } + else if (((hx - 0x3ff00000) | lx) == 0) + { + return 0.0; /* acosh(1) = 0 */ + } + else if (hx > 0x40000000) /* 2**28 > x > 2 */ + { + t = x * x; + return __ieee754_log (2.0 * x - one / (x + __ieee754_sqrt (t - one))); + } + else /* 1<x<2 */ + { + t = x - one; + return __log1p (t + __ieee754_sqrt (2.0 * t + t * t)); + } } strong_alias (__ieee754_acosh, __acosh_finite) diff --git a/sysdeps/ieee754/dbl-64/e_atan2.c b/sysdeps/ieee754/dbl-64/e_atan2.c index 4ebe9c01f9..e36305cda7 100644 --- a/sysdeps/ieee754/dbl-64/e_atan2.c +++ b/sysdeps/ieee754/dbl-64/e_atan2.c @@ -42,6 +42,7 @@ #include "uatan.tbl" #include "atnat2.h" #include <math_private.h> +#include <stap-probe.h> #ifndef SECTION # define SECTION @@ -71,14 +72,14 @@ __ieee754_atan2 (double y, double x) int i, de, ux, dx, uy, dy; static const int pr[MM] = { 6, 8, 10, 20, 32 }; double ax, ay, u, du, u9, ua, v, vv, dv, t1, t2, t3, t7, t8, - z, zz, cor, s1, ss1, s2, ss2; + z, zz, cor, s1, ss1, s2, ss2; #ifndef DLA_FMS double t4, t5, t6; #endif number num; - static const int ep = 59768832, /* 57*16**5 */ - em = -59768832; /* -57*16**5 */ + static const int ep = 59768832, /* 57*16**5 */ + em = -59768832; /* -57*16**5 */ /* x=NaN or y=NaN */ num.d = x; @@ -293,17 +294,17 @@ __ieee754_atan2 (double y, double x) if (i < 112) { if (i < 48) - u9 = u91.d; /* u < 1/4 */ + u9 = u91.d; /* u < 1/4 */ else u9 = u92.d; - } /* 1/4 <= u < 1/2 */ + } /* 1/4 <= u < 1/2 */ else { if (i < 176) - u9 = u93.d; /* 1/2 <= u < 3/4 */ + u9 = u93.d; /* 1/2 <= u < 3/4 */ else u9 = u94.d; - } /* 3/4 <= u <= 1 */ + } /* 3/4 <= u <= 1 */ if ((z = t1 + (zz - u9 * t1)) == t1 + (zz + u9 * t1)) return signArctan2 (y, z); @@ -311,9 +312,9 @@ __ieee754_atan2 (double y, double x) EADD (t1, du, v, vv); s1 = v * (hij[i][11].d + v * (hij[i][12].d - + v * (hij[i][13].d - + v * (hij[i][14].d - + v * hij[i][15].d)))); + + v * (hij[i][13].d + + v * (hij[i][14].d + + v * hij[i][15].d)))); ADD2 (hij[i][9].d, hij[i][10].d, s1, 0, s2, ss2, t1, t2); MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (hij[i][7].d, hij[i][8].d, s1, ss1, s2, ss2, t1, t2); @@ -597,7 +598,11 @@ atan2Mp (double x, double y, const int pr[]) __mp_dbl (&mpz1, &z1, p); __mp_dbl (&mpz2, &z2, p); if (z1 == z2) - return z1; + { + LIBC_PROBE (slowatan2, 4, &p, &x, &y, &z1); + return z1; + } } + LIBC_PROBE (slowatan2_inexact, 4, &p, &x, &y, &z1); return z1; /*if impossible to do exact computing */ } diff --git a/sysdeps/ieee754/dbl-64/e_cosh.c b/sysdeps/ieee754/dbl-64/e_cosh.c index 229d5a2fb3..6caf943ed0 100644 --- a/sysdeps/ieee754/dbl-64/e_cosh.c +++ b/sysdeps/ieee754/dbl-64/e_cosh.c @@ -34,49 +34,55 @@ #include <math.h> #include <math_private.h> -static const double one = 1.0, half=0.5, huge = 1.0e300; +static const double one = 1.0, half = 0.5, huge = 1.0e300; double __ieee754_cosh (double x) { - double t,w; - int32_t ix; - u_int32_t lx; + double t, w; + int32_t ix; + u_int32_t lx; - /* High word of |x|. */ - GET_HIGH_WORD(ix,x); - ix &= 0x7fffffff; + /* High word of |x|. */ + GET_HIGH_WORD (ix, x); + ix &= 0x7fffffff; - /* |x| in [0,22] */ - if (ix < 0x40360000) { - /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ - if(ix<0x3fd62e43) { - t = __expm1(fabs(x)); - w = one+t; - if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */ - return one+(t*t)/(w+w); - } - - /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ - t = __ieee754_exp(fabs(x)); - return half*t+half/t; + /* |x| in [0,22] */ + if (ix < 0x40360000) + { + /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ + if (ix < 0x3fd62e43) + { + t = __expm1 (fabs (x)); + w = one + t; + if (ix < 0x3c800000) + return w; /* cosh(tiny) = 1 */ + return one + (t * t) / (w + w); } - /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ - if (ix < 0x40862e42) return half*__ieee754_exp(fabs(x)); + /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ + t = __ieee754_exp (fabs (x)); + return half * t + half / t; + } - /* |x| in [log(maxdouble), overflowthresold] */ - GET_LOW_WORD(lx,x); - if (ix<0x408633ce || ((ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d))) { - w = __ieee754_exp(half*fabs(x)); - t = half*w; - return t*w; - } + /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ + if (ix < 0x40862e42) + return half * __ieee754_exp (fabs (x)); + + /* |x| in [log(maxdouble), overflowthresold] */ + GET_LOW_WORD (lx, x); + if (ix < 0x408633ce || ((ix == 0x408633ce) && (lx <= (u_int32_t) 0x8fb9f87d))) + { + w = __ieee754_exp (half * fabs (x)); + t = half * w; + return t * w; + } - /* x is INF or NaN */ - if(ix>=0x7ff00000) return x*x; + /* x is INF or NaN */ + if (ix >= 0x7ff00000) + return x * x; - /* |x| > overflowthresold, cosh(x) overflow */ - return huge*huge; + /* |x| > overflowthresold, cosh(x) overflow */ + return huge * huge; } strong_alias (__ieee754_cosh, __cosh_finite) diff --git a/sysdeps/ieee754/dbl-64/e_exp.c b/sysdeps/ieee754/dbl-64/e_exp.c index 07cc4a91b6..9d35e6d66c 100644 --- a/sysdeps/ieee754/dbl-64/e_exp.c +++ b/sysdeps/ieee754/dbl-64/e_exp.c @@ -39,226 +39,315 @@ #include "uexp.tbl" #include <math_private.h> #include <fenv.h> +#include <float.h> #ifndef SECTION # define SECTION #endif -double __slowexp(double); +double __slowexp (double); -/***************************************************************************/ -/* An ultimate exp routine. Given an IEEE double machine number x */ -/* it computes the correctly rounded (to nearest) value of e^x */ -/***************************************************************************/ +/* An ultimate exp routine. Given an IEEE double machine number x it computes + the correctly rounded (to nearest) value of e^x. */ double SECTION -__ieee754_exp(double x) { +__ieee754_exp (double x) +{ double bexp, t, eps, del, base, y, al, bet, res, rem, cor; - mynumber junk1, junk2, binexp = {{0,0}}; - int4 i,j,m,n,ex; + mynumber junk1, junk2, binexp = {{0, 0}}; + int4 i, j, m, n, ex; double retval; SET_RESTORE_ROUND (FE_TONEAREST); junk1.x = x; m = junk1.i[HIGH_HALF]; - n = m&hugeint; - - if (n > smallint && n < bigint) { - - y = x*log2e.x + three51.x; - bexp = y - three51.x; /* multiply the result by 2**bexp */ - - junk1.x = y; - - eps = bexp*ln_two2.x; /* x = bexp*ln(2) + t - eps */ - t = x - bexp*ln_two1.x; - - y = t + three33.x; - base = y - three33.x; /* t rounded to a multiple of 2**-18 */ - junk2.x = y; - del = (t - base) - eps; /* x = bexp*ln(2) + base + del */ - eps = del + del*del*(p3.x*del + p2.x); - - binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+1023)<<20; - - i = ((junk2.i[LOW_HALF]>>8)&0xfffffffe)+356; - j = (junk2.i[LOW_HALF]&511)<<1; - - al = coar.x[i]*fine.x[j]; - bet =(coar.x[i]*fine.x[j+1] + coar.x[i+1]*fine.x[j]) + coar.x[i+1]*fine.x[j+1]; - - rem=(bet + bet*eps)+al*eps; - res = al + rem; - cor = (al - res) + rem; - if (res == (res+cor*err_0)) { retval = res*binexp.x; goto ret; } - else { retval = __slowexp(x); goto ret; } /*if error is over bound */ - } + n = m & hugeint; + + if (n > smallint && n < bigint) + { + y = x * log2e.x + three51.x; + bexp = y - three51.x; /* multiply the result by 2**bexp */ + + junk1.x = y; + + eps = bexp * ln_two2.x; /* x = bexp*ln(2) + t - eps */ + t = x - bexp * ln_two1.x; + + y = t + three33.x; + base = y - three33.x; /* t rounded to a multiple of 2**-18 */ + junk2.x = y; + del = (t - base) - eps; /* x = bexp*ln(2) + base + del */ + eps = del + del * del * (p3.x * del + p2.x); + + binexp.i[HIGH_HALF] = (junk1.i[LOW_HALF] + 1023) << 20; + + i = ((junk2.i[LOW_HALF] >> 8) & 0xfffffffe) + 356; + j = (junk2.i[LOW_HALF] & 511) << 1; + + al = coar.x[i] * fine.x[j]; + bet = ((coar.x[i] * fine.x[j + 1] + coar.x[i + 1] * fine.x[j]) + + coar.x[i + 1] * fine.x[j + 1]); + + rem = (bet + bet * eps) + al * eps; + res = al + rem; + cor = (al - res) + rem; + if (res == (res + cor * err_0)) + { + retval = res * binexp.x; + goto ret; + } + else + { + retval = __slowexp (x); + goto ret; + } /*if error is over bound */ + } - if (n <= smallint) { retval = 1.0; goto ret; } + if (n <= smallint) + { + retval = 1.0; + goto ret; + } - if (n >= badint) { - if (n > infint) { retval = x+x; goto ret; } /* x is NaN */ - if (n < infint) { retval = (x>0) ? (hhuge*hhuge) : (tiny*tiny); goto ret; } - /* x is finite, cause either overflow or underflow */ - if (junk1.i[LOW_HALF] != 0) { retval = x+x; goto ret; } /* x is NaN */ - retval = (x>0)?inf.x:zero; /* |x| = inf; return either inf or 0 */ - goto ret; - } + if (n >= badint) + { + if (n > infint) + { + retval = x + x; + goto ret; + } /* x is NaN */ + if (n < infint) + { + retval = (x > 0) ? (hhuge * hhuge) : (tiny * tiny); + goto ret; + } + /* x is finite, cause either overflow or underflow */ + if (junk1.i[LOW_HALF] != 0) + { + retval = x + x; + goto ret; + } /* x is NaN */ + retval = (x > 0) ? inf.x : zero; /* |x| = inf; return either inf or 0 */ + goto ret; + } - y = x*log2e.x + three51.x; + y = x * log2e.x + three51.x; bexp = y - three51.x; junk1.x = y; - eps = bexp*ln_two2.x; - t = x - bexp*ln_two1.x; + eps = bexp * ln_two2.x; + t = x - bexp * ln_two1.x; y = t + three33.x; base = y - three33.x; junk2.x = y; del = (t - base) - eps; - eps = del + del*del*(p3.x*del + p2.x); - i = ((junk2.i[LOW_HALF]>>8)&0xfffffffe)+356; - j = (junk2.i[LOW_HALF]&511)<<1; - al = coar.x[i]*fine.x[j]; - bet =(coar.x[i]*fine.x[j+1] + coar.x[i+1]*fine.x[j]) + coar.x[i+1]*fine.x[j+1]; - rem=(bet + bet*eps)+al*eps; + eps = del + del * del * (p3.x * del + p2.x); + i = ((junk2.i[LOW_HALF] >> 8) & 0xfffffffe) + 356; + j = (junk2.i[LOW_HALF] & 511) << 1; + al = coar.x[i] * fine.x[j]; + bet = ((coar.x[i] * fine.x[j + 1] + coar.x[i + 1] * fine.x[j]) + + coar.x[i + 1] * fine.x[j + 1]); + rem = (bet + bet * eps) + al * eps; res = al + rem; cor = (al - res) + rem; - if (m>>31) { - ex=junk1.i[LOW_HALF]; - if (res < 1.0) {res+=res; cor+=cor; ex-=1;} - if (ex >=-1022) { - binexp.i[HIGH_HALF] = (1023+ex)<<20; - if (res == (res+cor*err_0)) { retval = res*binexp.x; goto ret; } - else { retval = __slowexp(x); goto ret; } /*if error is over bound */ - } - ex = -(1022+ex); - binexp.i[HIGH_HALF] = (1023-ex)<<20; - res*=binexp.x; - cor*=binexp.x; - eps=1.0000000001+err_0*binexp.x; - t=1.0+res; - y = ((1.0-t)+res)+cor; - res=t+y; - cor = (t-res)+y; - if (res == (res + eps*cor)) - { binexp.i[HIGH_HALF] = 0x00100000; - retval = (res-1.0)*binexp.x; + if (m >> 31) + { + ex = junk1.i[LOW_HALF]; + if (res < 1.0) + { + res += res; + cor += cor; + ex -= 1; + } + if (ex >= -1022) + { + binexp.i[HIGH_HALF] = (1023 + ex) << 20; + if (res == (res + cor * err_0)) + { + retval = res * binexp.x; + goto ret; + } + else + { + retval = __slowexp (x); + goto check_uflow_ret; + } /*if error is over bound */ + } + ex = -(1022 + ex); + binexp.i[HIGH_HALF] = (1023 - ex) << 20; + res *= binexp.x; + cor *= binexp.x; + eps = 1.0000000001 + err_0 * binexp.x; + t = 1.0 + res; + y = ((1.0 - t) + res) + cor; + res = t + y; + cor = (t - res) + y; + if (res == (res + eps * cor)) + { + binexp.i[HIGH_HALF] = 0x00100000; + retval = (res - 1.0) * binexp.x; + goto check_uflow_ret; + } + else + { + retval = __slowexp (x); + goto check_uflow_ret; + } /* if error is over bound */ + check_uflow_ret: + if (retval < DBL_MIN) + { +#if FLT_EVAL_METHOD != 0 + volatile +#endif + double force_underflow = tiny * tiny; + math_force_eval (force_underflow); + } goto ret; } - else { retval = __slowexp(x); goto ret; } /* if error is over bound */ - } - else { - binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+767)<<20; - if (res == (res+cor*err_0)) { retval = res*binexp.x*t256.x; goto ret; } - else { retval = __slowexp(x); goto ret; } - } - ret: + else + { + binexp.i[HIGH_HALF] = (junk1.i[LOW_HALF] + 767) << 20; + if (res == (res + cor * err_0)) + { + retval = res * binexp.x * t256.x; + goto ret; + } + else + { + retval = __slowexp (x); + goto ret; + } + } +ret: return retval; } #ifndef __ieee754_exp strong_alias (__ieee754_exp, __exp_finite) #endif -/************************************************************************/ -/* Compute e^(x+xx)(Double-Length number) .The routine also receive */ -/* bound of error of previous calculation .If after computing exp */ -/* error bigger than allows routine return non positive number */ -/*else return e^(x + xx) (always positive ) */ -/************************************************************************/ - +/* Compute e^(x+xx). The routine also receives bound of error of previous + calculation. If after computing exp the error exceeds the allowed bounds, + the routine returns a non-positive number. Otherwise it returns the + computed result, which is always positive. */ double SECTION -__exp1(double x, double xx, double error) { +__exp1 (double x, double xx, double error) +{ double bexp, t, eps, del, base, y, al, bet, res, rem, cor; - mynumber junk1, junk2, binexp = {{0,0}}; - int4 i,j,m,n,ex; + mynumber junk1, junk2, binexp = {{0, 0}}; + int4 i, j, m, n, ex; junk1.x = x; m = junk1.i[HIGH_HALF]; - n = m&hugeint; /* no sign */ - - if (n > smallint && n < bigint) { - y = x*log2e.x + three51.x; - bexp = y - three51.x; /* multiply the result by 2**bexp */ + n = m & hugeint; /* no sign */ - junk1.x = y; + if (n > smallint && n < bigint) + { + y = x * log2e.x + three51.x; + bexp = y - three51.x; /* multiply the result by 2**bexp */ - eps = bexp*ln_two2.x; /* x = bexp*ln(2) + t - eps */ - t = x - bexp*ln_two1.x; + junk1.x = y; - y = t + three33.x; - base = y - three33.x; /* t rounded to a multiple of 2**-18 */ - junk2.x = y; - del = (t - base) + (xx-eps); /* x = bexp*ln(2) + base + del */ - eps = del + del*del*(p3.x*del + p2.x); + eps = bexp * ln_two2.x; /* x = bexp*ln(2) + t - eps */ + t = x - bexp * ln_two1.x; - binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+1023)<<20; + y = t + three33.x; + base = y - three33.x; /* t rounded to a multiple of 2**-18 */ + junk2.x = y; + del = (t - base) + (xx - eps); /* x = bexp*ln(2) + base + del */ + eps = del + del * del * (p3.x * del + p2.x); - i = ((junk2.i[LOW_HALF]>>8)&0xfffffffe)+356; - j = (junk2.i[LOW_HALF]&511)<<1; + binexp.i[HIGH_HALF] = (junk1.i[LOW_HALF] + 1023) << 20; - al = coar.x[i]*fine.x[j]; - bet =(coar.x[i]*fine.x[j+1] + coar.x[i+1]*fine.x[j]) + coar.x[i+1]*fine.x[j+1]; + i = ((junk2.i[LOW_HALF] >> 8) & 0xfffffffe) + 356; + j = (junk2.i[LOW_HALF] & 511) << 1; - rem=(bet + bet*eps)+al*eps; - res = al + rem; - cor = (al - res) + rem; - if (res == (res+cor*(1.0+error+err_1))) return res*binexp.x; - else return -10.0; - } + al = coar.x[i] * fine.x[j]; + bet = ((coar.x[i] * fine.x[j + 1] + coar.x[i + 1] * fine.x[j]) + + coar.x[i + 1] * fine.x[j + 1]); - if (n <= smallint) return 1.0; /* if x->0 e^x=1 */ + rem = (bet + bet * eps) + al * eps; + res = al + rem; + cor = (al - res) + rem; + if (res == (res + cor * (1.0 + error + err_1))) + return res * binexp.x; + else + return -10.0; + } - if (n >= badint) { - if (n > infint) return(zero/zero); /* x is NaN, return invalid */ - if (n < infint) return ( (x>0) ? (hhuge*hhuge) : (tiny*tiny) ); - /* x is finite, cause either overflow or underflow */ - if (junk1.i[LOW_HALF] != 0) return (zero/zero); /* x is NaN */ - return ((x>0)?inf.x:zero ); /* |x| = inf; return either inf or 0 */ - } + if (n <= smallint) + return 1.0; /* if x->0 e^x=1 */ + + if (n >= badint) + { + if (n > infint) + return (zero / zero); /* x is NaN, return invalid */ + if (n < infint) + return ((x > 0) ? (hhuge * hhuge) : (tiny * tiny)); + /* x is finite, cause either overflow or underflow */ + if (junk1.i[LOW_HALF] != 0) + return (zero / zero); /* x is NaN */ + return ((x > 0) ? inf.x : zero); /* |x| = inf; return either inf or 0 */ + } - y = x*log2e.x + three51.x; + y = x * log2e.x + three51.x; bexp = y - three51.x; junk1.x = y; - eps = bexp*ln_two2.x; - t = x - bexp*ln_two1.x; + eps = bexp * ln_two2.x; + t = x - bexp * ln_two1.x; y = t + three33.x; base = y - three33.x; junk2.x = y; - del = (t - base) + (xx-eps); - eps = del + del*del*(p3.x*del + p2.x); - i = ((junk2.i[LOW_HALF]>>8)&0xfffffffe)+356; - j = (junk2.i[LOW_HALF]&511)<<1; - al = coar.x[i]*fine.x[j]; - bet =(coar.x[i]*fine.x[j+1] + coar.x[i+1]*fine.x[j]) + coar.x[i+1]*fine.x[j+1]; - rem=(bet + bet*eps)+al*eps; + del = (t - base) + (xx - eps); + eps = del + del * del * (p3.x * del + p2.x); + i = ((junk2.i[LOW_HALF] >> 8) & 0xfffffffe) + 356; + j = (junk2.i[LOW_HALF] & 511) << 1; + al = coar.x[i] * fine.x[j]; + bet = ((coar.x[i] * fine.x[j + 1] + coar.x[i + 1] * fine.x[j]) + + coar.x[i + 1] * fine.x[j + 1]); + rem = (bet + bet * eps) + al * eps; res = al + rem; cor = (al - res) + rem; - if (m>>31) { - ex=junk1.i[LOW_HALF]; - if (res < 1.0) {res+=res; cor+=cor; ex-=1;} - if (ex >=-1022) { - binexp.i[HIGH_HALF] = (1023+ex)<<20; - if (res == (res+cor*(1.0+error+err_1))) return res*binexp.x; - else return -10.0; + if (m >> 31) + { + ex = junk1.i[LOW_HALF]; + if (res < 1.0) + { + res += res; + cor += cor; + ex -= 1; + } + if (ex >= -1022) + { + binexp.i[HIGH_HALF] = (1023 + ex) << 20; + if (res == (res + cor * (1.0 + error + err_1))) + return res * binexp.x; + else + return -10.0; + } + ex = -(1022 + ex); + binexp.i[HIGH_HALF] = (1023 - ex) << 20; + res *= binexp.x; + cor *= binexp.x; + eps = 1.00000000001 + (error + err_1) * binexp.x; + t = 1.0 + res; + y = ((1.0 - t) + res) + cor; + res = t + y; + cor = (t - res) + y; + if (res == (res + eps * cor)) + { + binexp.i[HIGH_HALF] = 0x00100000; + return (res - 1.0) * binexp.x; + } + else + return -10.0; + } + else + { + binexp.i[HIGH_HALF] = (junk1.i[LOW_HALF] + 767) << 20; + if (res == (res + cor * (1.0 + error + err_1))) + return res * binexp.x * t256.x; + else + return -10.0; } - ex = -(1022+ex); - binexp.i[HIGH_HALF] = (1023-ex)<<20; - res*=binexp.x; - cor*=binexp.x; - eps=1.00000000001+(error+err_1)*binexp.x; - t=1.0+res; - y = ((1.0-t)+res)+cor; - res=t+y; - cor = (t-res)+y; - if (res == (res + eps*cor)) - {binexp.i[HIGH_HALF] = 0x00100000; return (res-1.0)*binexp.x;} - else return -10.0; - } - else { - binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+767)<<20; - if (res == (res+cor*(1.0+error+err_1))) - return res*binexp.x*t256.x; - else return -10.0; - } } diff --git a/sysdeps/ieee754/dbl-64/e_exp2.c b/sysdeps/ieee754/dbl-64/e_exp2.c index 96ec735e3f..e1ba940e6c 100644 --- a/sysdeps/ieee754/dbl-64/e_exp2.c +++ b/sysdeps/ieee754/dbl-64/e_exp2.c @@ -46,7 +46,7 @@ __ieee754_exp2 (double x) if (__builtin_expect (isless (x, himark), 1)) { /* Exceptional cases: */ - if (__builtin_expect (! isgreaterequal (x, lomark), 0)) + if (__builtin_expect (!isgreaterequal (x, lomark), 0)) { if (__isinf (x)) /* e^-inf == 0, with no error. */ @@ -93,7 +93,7 @@ __ieee754_exp2 (double x) /* 3. Compute ex2 = 2^(t/512+e+ex). */ ex2_u.d = exp2_accuratetable[tval & 511]; tval >>= 9; - unsafe = abs(tval) >= -DBL_MIN_EXP - 1; + unsafe = abs (tval) >= -DBL_MIN_EXP - 1; ex2_u.ieee.exponent += tval >> unsafe; scale_u.d = 1.0; scale_u.ieee.exponent += tval - (tval >> unsafe); @@ -106,7 +106,7 @@ __ieee754_exp2 (double x) * x + .055504110254308625) * x + .240226506959100583) * x + .69314718055994495) * ex2_u.d; - math_opt_barrier (x22); + math_opt_barrier (x22); } /* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex). */ @@ -119,6 +119,6 @@ __ieee754_exp2 (double x) } else /* Return x, if x is a NaN or Inf; or overflow, otherwise. */ - return TWO1023*x; + return TWO1023 * x; } strong_alias (__ieee754_exp2, __exp2_finite) diff --git a/sysdeps/ieee754/dbl-64/e_fmod.c b/sysdeps/ieee754/dbl-64/e_fmod.c index b8548fae4b..c83c2aedb2 100644 --- a/sysdeps/ieee754/dbl-64/e_fmod.c +++ b/sysdeps/ieee754/dbl-64/e_fmod.c @@ -18,111 +18,156 @@ #include <math.h> #include <math_private.h> -static const double one = 1.0, Zero[] = {0.0, -0.0,}; +static const double one = 1.0, Zero[] = { 0.0, -0.0, }; double __ieee754_fmod (double x, double y) { - int32_t n,hx,hy,hz,ix,iy,sx,i; - u_int32_t lx,ly,lz; + int32_t n, hx, hy, hz, ix, iy, sx, i; + u_int32_t lx, ly, lz; - EXTRACT_WORDS(hx,lx,x); - EXTRACT_WORDS(hy,ly,y); - sx = hx&0x80000000; /* sign of x */ - hx ^=sx; /* |x| */ - hy &= 0x7fffffff; /* |y| */ + EXTRACT_WORDS (hx, lx, x); + EXTRACT_WORDS (hy, ly, y); + sx = hx & 0x80000000; /* sign of x */ + hx ^= sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ - /* purge off exception values */ - if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */ - ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */ - return (x*y)/(x*y); - if(hx<=hy) { - if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */ - if(lx==ly) - return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/ - } + /* purge off exception values */ + if ((hy | ly) == 0 || (hx >= 0x7ff00000) || /* y=0,or x not finite */ + ((hy | ((ly | -ly) >> 31)) > 0x7ff00000)) /* or y is NaN */ + return (x * y) / (x * y); + if (hx <= hy) + { + if ((hx < hy) || (lx < ly)) + return x; /* |x|<|y| return x */ + if (lx == ly) + return Zero[(u_int32_t) sx >> 31]; /* |x|=|y| return x*0*/ + } - /* determine ix = ilogb(x) */ - if(__builtin_expect(hx<0x00100000, 0)) { /* subnormal x */ - if(hx==0) { - for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; - } else { - for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1; - } - } else ix = (hx>>20)-1023; + /* determine ix = ilogb(x) */ + if (__builtin_expect (hx < 0x00100000, 0)) /* subnormal x */ + { + if (hx == 0) + { + for (ix = -1043, i = lx; i > 0; i <<= 1) + ix -= 1; + } + else + { + for (ix = -1022, i = (hx << 11); i > 0; i <<= 1) + ix -= 1; + } + } + else + ix = (hx >> 20) - 1023; - /* determine iy = ilogb(y) */ - if(__builtin_expect(hy<0x00100000, 0)) { /* subnormal y */ - if(hy==0) { - for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; - } else { - for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1; - } - } else iy = (hy>>20)-1023; + /* determine iy = ilogb(y) */ + if (__builtin_expect (hy < 0x00100000, 0)) /* subnormal y */ + { + if (hy == 0) + { + for (iy = -1043, i = ly; i > 0; i <<= 1) + iy -= 1; + } + else + { + for (iy = -1022, i = (hy << 11); i > 0; i <<= 1) + iy -= 1; + } + } + else + iy = (hy >> 20) - 1023; - /* set up {hx,lx}, {hy,ly} and align y to x */ - if(__builtin_expect(ix >= -1022, 1)) - hx = 0x00100000|(0x000fffff&hx); - else { /* subnormal x, shift x to normal */ - n = -1022-ix; - if(n<=31) { - hx = (hx<<n)|(lx>>(32-n)); - lx <<= n; - } else { - hx = lx<<(n-32); - lx = 0; - } + /* set up {hx,lx}, {hy,ly} and align y to x */ + if (__builtin_expect (ix >= -1022, 1)) + hx = 0x00100000 | (0x000fffff & hx); + else /* subnormal x, shift x to normal */ + { + n = -1022 - ix; + if (n <= 31) + { + hx = (hx << n) | (lx >> (32 - n)); + lx <<= n; + } + else + { + hx = lx << (n - 32); + lx = 0; + } + } + if (__builtin_expect (iy >= -1022, 1)) + hy = 0x00100000 | (0x000fffff & hy); + else /* subnormal y, shift y to normal */ + { + n = -1022 - iy; + if (n <= 31) + { + hy = (hy << n) | (ly >> (32 - n)); + ly <<= n; } - if(__builtin_expect(iy >= -1022, 1)) - hy = 0x00100000|(0x000fffff&hy); - else { /* subnormal y, shift y to normal */ - n = -1022-iy; - if(n<=31) { - hy = (hy<<n)|(ly>>(32-n)); - ly <<= n; - } else { - hy = ly<<(n-32); - ly = 0; - } + else + { + hy = ly << (n - 32); + ly = 0; } + } - /* fix point fmod */ - n = ix - iy; - while(n--) { - hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; - if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;} - else { - if((hz|lz)==0) /* return sign(x)*0 */ - return Zero[(u_int32_t)sx>>31]; - hx = hz+hz+(lz>>31); lx = lz+lz; - } + /* fix point fmod */ + n = ix - iy; + while (n--) + { + hz = hx - hy; lz = lx - ly; if (lx < ly) + hz -= 1; + if (hz < 0) + { + hx = hx + hx + (lx >> 31); lx = lx + lx; } - hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; - if(hz>=0) {hx=hz;lx=lz;} + else + { + if ((hz | lz) == 0) /* return sign(x)*0 */ + return Zero[(u_int32_t) sx >> 31]; + hx = hz + hz + (lz >> 31); lx = lz + lz; + } + } + hz = hx - hy; lz = lx - ly; if (lx < ly) + hz -= 1; + if (hz >= 0) + { + hx = hz; lx = lz; + } - /* convert back to floating value and restore the sign */ - if((hx|lx)==0) /* return sign(x)*0 */ - return Zero[(u_int32_t)sx>>31]; - while(hx<0x00100000) { /* normalize x */ - hx = hx+hx+(lx>>31); lx = lx+lx; - iy -= 1; + /* convert back to floating value and restore the sign */ + if ((hx | lx) == 0) /* return sign(x)*0 */ + return Zero[(u_int32_t) sx >> 31]; + while (hx < 0x00100000) /* normalize x */ + { + hx = hx + hx + (lx >> 31); lx = lx + lx; + iy -= 1; + } + if (__builtin_expect (iy >= -1022, 1)) /* normalize output */ + { + hx = ((hx - 0x00100000) | ((iy + 1023) << 20)); + INSERT_WORDS (x, hx | sx, lx); + } + else /* subnormal output */ + { + n = -1022 - iy; + if (n <= 20) + { + lx = (lx >> n) | ((u_int32_t) hx << (32 - n)); + hx >>= n; + } + else if (n <= 31) + { + lx = (hx << (32 - n)) | (lx >> n); hx = sx; } - if(__builtin_expect(iy>= -1022, 1)) { /* normalize output */ - hx = ((hx-0x00100000)|((iy+1023)<<20)); - INSERT_WORDS(x,hx|sx,lx); - } else { /* subnormal output */ - n = -1022 - iy; - if(n<=20) { - lx = (lx>>n)|((u_int32_t)hx<<(32-n)); - hx >>= n; - } else if (n<=31) { - lx = (hx<<(32-n))|(lx>>n); hx = sx; - } else { - lx = hx>>(n-32); hx = sx; - } - INSERT_WORDS(x,hx|sx,lx); - x *= one; /* create necessary signal */ + else + { + lx = hx >> (n - 32); hx = sx; } - return x; /* exact output */ + INSERT_WORDS (x, hx | sx, lx); + x *= one; /* create necessary signal */ + } + return x; /* exact output */ } strong_alias (__ieee754_fmod, __fmod_finite) diff --git a/sysdeps/ieee754/dbl-64/e_gamma_r.c b/sysdeps/ieee754/dbl-64/e_gamma_r.c index 5b17f7b5ad..13e389d7c1 100644 --- a/sysdeps/ieee754/dbl-64/e_gamma_r.c +++ b/sysdeps/ieee754/dbl-64/e_gamma_r.c @@ -135,7 +135,7 @@ __ieee754_gamma_r (double x, int *signgamp) *signgamp = 0; return (x - x) / (x - x); } - if (__builtin_expect ((unsigned int) hx == 0xfff00000 && lx==0, 0)) + if (__builtin_expect ((unsigned int) hx == 0xfff00000 && lx == 0, 0)) { /* x == -Inf. According to ISO this is NaN. */ *signgamp = 0; diff --git a/sysdeps/ieee754/dbl-64/e_hypot.c b/sysdeps/ieee754/dbl-64/e_hypot.c index 2dd681cf1a..88242bc4f6 100644 --- a/sysdeps/ieee754/dbl-64/e_hypot.c +++ b/sysdeps/ieee754/dbl-64/e_hypot.c @@ -46,76 +46,112 @@ #include <math_private.h> double -__ieee754_hypot(double x, double y) +__ieee754_hypot (double x, double y) { - double a,b,t1,t2,y1,y2,w; - int32_t j,k,ha,hb; + double a, b, t1, t2, y1, y2, w; + int32_t j, k, ha, hb; - GET_HIGH_WORD(ha,x); - ha &= 0x7fffffff; - GET_HIGH_WORD(hb,y); - hb &= 0x7fffffff; - if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} - SET_HIGH_WORD(a,ha); /* a <- |a| */ - SET_HIGH_WORD(b,hb); /* b <- |b| */ - if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */ - k=0; - if(__builtin_expect(ha > 0x5f300000, 0)) { /* a>2**500 */ - if(ha >= 0x7ff00000) { /* Inf or NaN */ - u_int32_t low; - w = a+b; /* for sNaN */ - GET_LOW_WORD(low,a); - if(((ha&0xfffff)|low)==0) w = a; - GET_LOW_WORD(low,b); - if(((hb^0x7ff00000)|low)==0) w = b; - return w; - } - /* scale a and b by 2**-600 */ - ha -= 0x25800000; hb -= 0x25800000; k += 600; - SET_HIGH_WORD(a,ha); - SET_HIGH_WORD(b,hb); + GET_HIGH_WORD (ha, x); + ha &= 0x7fffffff; + GET_HIGH_WORD (hb, y); + hb &= 0x7fffffff; + if (hb > ha) + { + a = y; b = x; j = ha; ha = hb; hb = j; + } + else + { + a = x; b = y; + } + SET_HIGH_WORD (a, ha); /* a <- |a| */ + SET_HIGH_WORD (b, hb); /* b <- |b| */ + if ((ha - hb) > 0x3c00000) + { + return a + b; + } /* x/y > 2**60 */ + k = 0; + if (__builtin_expect (ha > 0x5f300000, 0)) /* a>2**500 */ + { + if (ha >= 0x7ff00000) /* Inf or NaN */ + { + u_int32_t low; + w = a + b; /* for sNaN */ + GET_LOW_WORD (low, a); + if (((ha & 0xfffff) | low) == 0) + w = a; + GET_LOW_WORD (low, b); + if (((hb ^ 0x7ff00000) | low) == 0) + w = b; + return w; } - if(__builtin_expect(hb < 0x20b00000, 0)) { /* b < 2**-500 */ - if(hb <= 0x000fffff) { /* subnormal b or 0 */ - u_int32_t low; - GET_LOW_WORD(low,b); - if((hb|low)==0) return a; - t1=0; - SET_HIGH_WORD(t1,0x7fd00000); /* t1=2^1022 */ - b *= t1; - a *= t1; - k -= 1022; - } else { /* scale a and b by 2^600 */ - ha += 0x25800000; /* a *= 2^600 */ - hb += 0x25800000; /* b *= 2^600 */ - k -= 600; - SET_HIGH_WORD(a,ha); - SET_HIGH_WORD(b,hb); + /* scale a and b by 2**-600 */ + ha -= 0x25800000; hb -= 0x25800000; k += 600; + SET_HIGH_WORD (a, ha); + SET_HIGH_WORD (b, hb); + } + if (__builtin_expect (hb < 0x23d00000, 0)) /* b < 2**-450 */ + { + if (hb <= 0x000fffff) /* subnormal b or 0 */ + { + u_int32_t low; + GET_LOW_WORD (low, b); + if ((hb | low) == 0) + return a; + t1 = 0; + SET_HIGH_WORD (t1, 0x7fd00000); /* t1=2^1022 */ + b *= t1; + a *= t1; + k -= 1022; + GET_HIGH_WORD (ha, a); + GET_HIGH_WORD (hb, b); + if (hb > ha) + { + t1 = a; + a = b; + b = t1; + j = ha; + ha = hb; + hb = j; } } - /* medium size a and b */ - w = a-b; - if (w>b) { - t1 = 0; - SET_HIGH_WORD(t1,ha); - t2 = a-t1; - w = __ieee754_sqrt(t1*t1-(b*(-b)-t2*(a+t1))); - } else { - a = a+a; - y1 = 0; - SET_HIGH_WORD(y1,hb); - y2 = b - y1; - t1 = 0; - SET_HIGH_WORD(t1,ha+0x00100000); - t2 = a - t1; - w = __ieee754_sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b))); + else /* scale a and b by 2^600 */ + { + ha += 0x25800000; /* a *= 2^600 */ + hb += 0x25800000; /* b *= 2^600 */ + k -= 600; + SET_HIGH_WORD (a, ha); + SET_HIGH_WORD (b, hb); } - if(k!=0) { - u_int32_t high; - t1 = 1.0; - GET_HIGH_WORD(high,t1); - SET_HIGH_WORD(t1,high+(k<<20)); - return t1*w; - } else return w; + } + /* medium size a and b */ + w = a - b; + if (w > b) + { + t1 = 0; + SET_HIGH_WORD (t1, ha); + t2 = a - t1; + w = __ieee754_sqrt (t1 * t1 - (b * (-b) - t2 * (a + t1))); + } + else + { + a = a + a; + y1 = 0; + SET_HIGH_WORD (y1, hb); + y2 = b - y1; + t1 = 0; + SET_HIGH_WORD (t1, ha + 0x00100000); + t2 = a - t1; + w = __ieee754_sqrt (t1 * y1 - (w * (-w) - (t1 * y2 + t2 * b))); + } + if (k != 0) + { + u_int32_t high; + t1 = 1.0; + GET_HIGH_WORD (high, t1); + SET_HIGH_WORD (t1, high + (k << 20)); + return t1 * w; + } + else + return w; } strong_alias (__ieee754_hypot, __hypot_finite) diff --git a/sysdeps/ieee754/dbl-64/e_ilogb.c b/sysdeps/ieee754/dbl-64/e_ilogb.c index 0452a71fb8..1e338a59c1 100644 --- a/sysdeps/ieee754/dbl-64/e_ilogb.c +++ b/sysdeps/ieee754/dbl-64/e_ilogb.c @@ -25,30 +25,39 @@ static char rcsid[] = "$NetBSD: s_ilogb.c,v 1.9 1995/05/10 20:47:28 jtc Exp $"; #include <math.h> #include <math_private.h> -int __ieee754_ilogb(double x) +int +__ieee754_ilogb (double x) { - int32_t hx,lx,ix; + int32_t hx, lx, ix; - GET_HIGH_WORD(hx,x); - hx &= 0x7fffffff; - if(hx<0x00100000) { - GET_LOW_WORD(lx,x); - if((hx|lx)==0) - return FP_ILOGB0; /* ilogb(0) = FP_ILOGB0 */ - else /* subnormal x */ - if(hx==0) { - for (ix = -1043; lx>0; lx<<=1) ix -=1; - } else { - for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1; - } - return ix; + GET_HIGH_WORD (hx, x); + hx &= 0x7fffffff; + if (hx < 0x00100000) + { + GET_LOW_WORD (lx, x); + if ((hx | lx) == 0) + return FP_ILOGB0; /* ilogb(0) = FP_ILOGB0 */ + else /* subnormal x */ + if (hx == 0) + { + for (ix = -1043; lx > 0; lx <<= 1) + ix -= 1; } - else if (hx<0x7ff00000) return (hx>>20)-1023; - else if (FP_ILOGBNAN != INT_MAX) { - /* ISO C99 requires ilogb(+-Inf) == INT_MAX. */ - GET_LOW_WORD(lx,x); - if(((hx^0x7ff00000)|lx) == 0) - return INT_MAX; + else + { + for (ix = -1022, hx <<= 11; hx > 0; hx <<= 1) + ix -= 1; } - return FP_ILOGBNAN; + return ix; + } + else if (hx < 0x7ff00000) + return (hx >> 20) - 1023; + else if (FP_ILOGBNAN != INT_MAX) + { + /* ISO C99 requires ilogb(+-Inf) == INT_MAX. */ + GET_LOW_WORD (lx, x); + if (((hx ^ 0x7ff00000) | lx) == 0) + return INT_MAX; + } + return FP_ILOGBNAN; } diff --git a/sysdeps/ieee754/dbl-64/e_j0.c b/sysdeps/ieee754/dbl-64/e_j0.c index d641a09149..d165e80925 100644 --- a/sysdeps/ieee754/dbl-64/e_j0.c +++ b/sysdeps/ieee754/dbl-64/e_j0.c @@ -11,7 +11,7 @@ */ /* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/26, for performance improvement on pipelined processors. -*/ + */ /* __ieee754_j0(x), __ieee754_y0(x) * Bessel function of the first and second kinds of order zero. @@ -61,154 +61,166 @@ #include <math.h> #include <math_private.h> -static double pzero(double), qzero(double); +static double pzero (double), qzero (double); static const double -huge = 1e300, -one = 1.0, -invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ -tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ - /* R0/S0 on [0, 2.00] */ -R[] = {0.0, 0.0, 1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */ - -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */ - 1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */ - -4.61832688532103189199e-09}, /* 0xBE33D5E7, 0x73D63FCE */ -S[] = {0.0, 1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */ - 1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */ - 5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */ - 1.16614003333790000205e-09}; /* 0x3E1408BC, 0xF4745D8F */ + huge = 1e300, + one = 1.0, + invsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ + tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ +/* R0/S0 on [0, 2.00] */ + R[] = { 0.0, 0.0, 1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */ + -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */ + 1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */ + -4.61832688532103189199e-09 }, /* 0xBE33D5E7, 0x73D63FCE */ + S[] = { 0.0, 1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */ + 1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */ + 5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */ + 1.16614003333790000205e-09 }; /* 0x3E1408BC, 0xF4745D8F */ static const double zero = 0.0; double -__ieee754_j0(double x) +__ieee754_j0 (double x) { - double z, s,c,ss,cc,r,u,v,r1,r2,s1,s2,z2,z4; - int32_t hx,ix; + double z, s, c, ss, cc, r, u, v, r1, r2, s1, s2, z2, z4; + int32_t hx, ix; - GET_HIGH_WORD(hx,x); - ix = hx&0x7fffffff; - if(ix>=0x7ff00000) return one/(x*x); - x = fabs(x); - if(ix >= 0x40000000) { /* |x| >= 2.0 */ - __sincos (x, &s, &c); - ss = s-c; - cc = s+c; - if(ix<0x7fe00000) { /* make sure x+x not overflow */ - z = -__cos(x+x); - if ((s*c)<zero) cc = z/ss; - else ss = z/cc; - } - /* - * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) - * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) - */ - if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrt(x); - else { - u = pzero(x); v = qzero(x); - z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrt(x); - } - return z; - } - if(ix<0x3f200000) { /* |x| < 2**-13 */ - math_force_eval(huge+x); /* raise inexact if x != 0 */ - if(ix<0x3e400000) return one; /* |x|<2**-27 */ - else return one - 0.25*x*x; + GET_HIGH_WORD (hx, x); + ix = hx & 0x7fffffff; + if (ix >= 0x7ff00000) + return one / (x * x); + x = fabs (x); + if (ix >= 0x40000000) /* |x| >= 2.0 */ + { + __sincos (x, &s, &c); + ss = s - c; + cc = s + c; + if (ix < 0x7fe00000) /* make sure x+x not overflow */ + { + z = -__cos (x + x); + if ((s * c) < zero) + cc = z / ss; + else + ss = z / cc; } - z = x*x; -#ifdef DO_NOT_USE_THIS - r = z*(R02+z*(R03+z*(R04+z*R05))); - s = one+z*(S01+z*(S02+z*(S03+z*S04))); -#else - r1 = z*R[2]; z2=z*z; - r2 = R[3]+z*R[4]; z4=z2*z2; - r = r1 + z2*r2 + z4*R[5]; - s1 = one+z*S[1]; - s2 = S[2]+z*S[3]; - s = s1 + z2*s2 + z4*S[4]; -#endif - if(ix < 0x3FF00000) { /* |x| < 1.00 */ - return one + z*(-0.25+(r/s)); - } else { - u = 0.5*x; - return((one+u)*(one-u)+z*(r/s)); + /* + * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + */ + if (ix > 0x48000000) + z = (invsqrtpi * cc) / __ieee754_sqrt (x); + else + { + u = pzero (x); v = qzero (x); + z = invsqrtpi * (u * cc - v * ss) / __ieee754_sqrt (x); } + return z; + } + if (ix < 0x3f200000) /* |x| < 2**-13 */ + { + math_force_eval (huge + x); /* raise inexact if x != 0 */ + if (ix < 0x3e400000) + return one; /* |x|<2**-27 */ + else + return one - 0.25 * x * x; + } + z = x * x; + r1 = z * R[2]; z2 = z * z; + r2 = R[3] + z * R[4]; z4 = z2 * z2; + r = r1 + z2 * r2 + z4 * R[5]; + s1 = one + z * S[1]; + s2 = S[2] + z * S[3]; + s = s1 + z2 * s2 + z4 * S[4]; + if (ix < 0x3FF00000) /* |x| < 1.00 */ + { + return one + z * (-0.25 + (r / s)); + } + else + { + u = 0.5 * x; + return ((one + u) * (one - u) + z * (r / s)); + } } strong_alias (__ieee754_j0, __j0_finite) static const double -U[] = {-7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */ - 1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */ - -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */ - 3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */ - -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */ - 1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */ - -3.98205194132103398453e-11}, /* 0xBDC5E43D, 0x693FB3C8 */ -V[] = {1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */ - 7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */ - 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */ - 4.41110311332675467403e-10}; /* 0x3DFE5018, 0x3BD6D9EF */ +U[] = { -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */ + 1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */ + -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */ + 3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */ + -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */ + 1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */ + -3.98205194132103398453e-11 }, /* 0xBDC5E43D, 0x693FB3C8 */ +V[] = { 1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */ + 7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */ + 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */ + 4.41110311332675467403e-10 }; /* 0x3DFE5018, 0x3BD6D9EF */ double -__ieee754_y0(double x) +__ieee754_y0 (double x) { - double z, s,c,ss,cc,u,v,z2,z4,z6,u1,u2,u3,v1,v2; - int32_t hx,ix,lx; + double z, s, c, ss, cc, u, v, z2, z4, z6, u1, u2, u3, v1, v2; + int32_t hx, ix, lx; - EXTRACT_WORDS(hx,lx,x); - ix = 0x7fffffff&hx; - /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0, y0(0) is -inf. */ - if(ix>=0x7ff00000) return one/(x+x*x); - if((ix|lx)==0) return -HUGE_VAL+x; /* -inf and overflow exception. */ - if(hx<0) return zero/(zero*x); - if(ix >= 0x40000000) { /* |x| >= 2.0 */ - /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) - * where x0 = x-pi/4 - * Better formula: - * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) - * = 1/sqrt(2) * (sin(x) + cos(x)) - * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) - * = 1/sqrt(2) * (sin(x) - cos(x)) - * To avoid cancellation, use - * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) - * to compute the worse one. - */ - __sincos (x, &s, &c); - ss = s-c; - cc = s+c; - /* - * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) - * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) - */ - if(ix<0x7fe00000) { /* make sure x+x not overflow */ - z = -__cos(x+x); - if ((s*c)<zero) cc = z/ss; - else ss = z/cc; - } - if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrt(x); - else { - u = pzero(x); v = qzero(x); - z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrt(x); - } - return z; + EXTRACT_WORDS (hx, lx, x); + ix = 0x7fffffff & hx; + /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0, y0(0) is -inf. */ + if (ix >= 0x7ff00000) + return one / (x + x * x); + if ((ix | lx) == 0) + return -HUGE_VAL + x; /* -inf and overflow exception. */ + if (hx < 0) + return zero / (zero * x); + if (ix >= 0x40000000) /* |x| >= 2.0 */ + { /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) + * where x0 = x-pi/4 + * Better formula: + * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + * = 1/sqrt(2) * (sin(x) + cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + __sincos (x, &s, &c); + ss = s - c; + cc = s + c; + /* + * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + */ + if (ix < 0x7fe00000) /* make sure x+x not overflow */ + { + z = -__cos (x + x); + if ((s * c) < zero) + cc = z / ss; + else + ss = z / cc; } - if(ix<=0x3e400000) { /* x < 2**-27 */ - return(U[0] + tpi*__ieee754_log(x)); + if (ix > 0x48000000) + z = (invsqrtpi * ss) / __ieee754_sqrt (x); + else + { + u = pzero (x); v = qzero (x); + z = invsqrtpi * (u * ss + v * cc) / __ieee754_sqrt (x); } - z = x*x; -#ifdef DO_NOT_USE_THIS - u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); - v = one+z*(v01+z*(v02+z*(v03+z*v04))); -#else - u1 = U[0]+z*U[1]; z2=z*z; - u2 = U[2]+z*U[3]; z4=z2*z2; - u3 = U[4]+z*U[5]; z6=z4*z2; - u = u1 + z2*u2 + z4*u3 + z6*U[6]; - v1 = one+z*V[0]; - v2 = V[1]+z*V[2]; - v = v1 + z2*v2 + z4*V[3]; -#endif - return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x))); + return z; + } + if (ix <= 0x3e400000) /* x < 2**-27 */ + { + return (U[0] + tpi * __ieee754_log (x)); + } + z = x * x; + u1 = U[0] + z * U[1]; z2 = z * z; + u2 = U[2] + z * U[3]; z4 = z2 * z2; + u3 = U[4] + z * U[5]; z6 = z4 * z2; + u = u1 + z2 * u2 + z4 * u3 + z6 * U[6]; + v1 = one + z * V[0]; + v2 = V[1] + z * V[2]; + v = v1 + z2 * v2 + z4 * V[3]; + return (u / v + tpi * (__ieee754_j0 (x) * __ieee754_log (x))); } strong_alias (__ieee754_y0, __y0_finite) @@ -286,33 +298,43 @@ static const double pS2[5] = { }; static double -pzero(double x) +pzero (double x) { - const double *p,*q; - double z,r,s,z2,z4,r1,r2,r3,s1,s2,s3; - int32_t ix; - GET_HIGH_WORD(ix,x); - ix &= 0x7fffffff; - if (ix>=0x41b00000) {return one;} - else if(ix>=0x40200000){p = pR8; q= pS8;} - else if(ix>=0x40122E8B){p = pR5; q= pS5;} - else if(ix>=0x4006DB6D){p = pR3; q= pS3;} - else if(ix>=0x40000000){p = pR2; q= pS2;} - z = one/(x*x); -#ifdef DO_NOT_USE_THIS - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); -#else - r1 = p[0]+z*p[1]; z2=z*z; - r2 = p[2]+z*p[3]; z4=z2*z2; - r3 = p[4]+z*p[5]; - r = r1 + z2*r2 + z4*r3; - s1 = one+z*q[0]; - s2 = q[1]+z*q[2]; - s3 = q[3]+z*q[4]; - s = s1 + z2*s2 + z4*s3; -#endif - return one+ r/s; + const double *p, *q; + double z, r, s, z2, z4, r1, r2, r3, s1, s2, s3; + int32_t ix; + GET_HIGH_WORD (ix, x); + ix &= 0x7fffffff; + if (ix >= 0x41b00000) + { + return one; + } + else if (ix >= 0x40200000) + { + p = pR8; q = pS8; + } + else if (ix >= 0x40122E8B) + { + p = pR5; q = pS5; + } + else if (ix >= 0x4006DB6D) + { + p = pR3; q = pS3; + } + else if (ix >= 0x40000000) + { + p = pR2; q = pS2; + } + z = one / (x * x); + r1 = p[0] + z * p[1]; z2 = z * z; + r2 = p[2] + z * p[3]; z4 = z2 * z2; + r3 = p[4] + z * p[5]; + r = r1 + z2 * r2 + z4 * r3; + s1 = one + z * q[0]; + s2 = q[1] + z * q[2]; + s3 = q[3] + z * q[4]; + s = s1 + z2 * s2 + z4 * s3; + return one + r / s; } @@ -394,31 +416,41 @@ static const double qS2[6] = { }; static double -qzero(double x) +qzero (double x) { - const double *p,*q; - double s,r,z,z2,z4,z6,r1,r2,r3,s1,s2,s3; - int32_t ix; - GET_HIGH_WORD(ix,x); - ix &= 0x7fffffff; - if (ix>=0x41b00000) {return -.125/x;} - else if(ix>=0x40200000){p = qR8; q= qS8;} - else if(ix>=0x40122E8B){p = qR5; q= qS5;} - else if(ix>=0x4006DB6D){p = qR3; q= qS3;} - else if(ix>=0x40000000){p = qR2; q= qS2;} - z = one/(x*x); -#ifdef DO_NOT_USE_THIS - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); -#else - r1 = p[0]+z*p[1]; z2=z*z; - r2 = p[2]+z*p[3]; z4=z2*z2; - r3 = p[4]+z*p[5]; z6=z4*z2; - r= r1 + z2*r2 + z4*r3; - s1 = one+z*q[0]; - s2 = q[1]+z*q[2]; - s3 = q[3]+z*q[4]; - s = s1 + z2*s2 + z4*s3 +z6*q[5]; -#endif - return (-.125 + r/s)/x; + const double *p, *q; + double s, r, z, z2, z4, z6, r1, r2, r3, s1, s2, s3; + int32_t ix; + GET_HIGH_WORD (ix, x); + ix &= 0x7fffffff; + if (ix >= 0x41b00000) + { + return -.125 / x; + } + else if (ix >= 0x40200000) + { + p = qR8; q = qS8; + } + else if (ix >= 0x40122E8B) + { + p = qR5; q = qS5; + } + else if (ix >= 0x4006DB6D) + { + p = qR3; q = qS3; + } + else if (ix >= 0x40000000) + { + p = qR2; q = qS2; + } + z = one / (x * x); + r1 = p[0] + z * p[1]; z2 = z * z; + r2 = p[2] + z * p[3]; z4 = z2 * z2; + r3 = p[4] + z * p[5]; z6 = z4 * z2; + r = r1 + z2 * r2 + z4 * r3; + s1 = one + z * q[0]; + s2 = q[1] + z * q[2]; + s3 = q[3] + z * q[4]; + s = s1 + z2 * s2 + z4 * s3 + z6 * q[5]; + return (-.125 + r / s) / x; } diff --git a/sysdeps/ieee754/dbl-64/e_j1.c b/sysdeps/ieee754/dbl-64/e_j1.c index cca5f20b4f..ab754c6ee0 100644 --- a/sysdeps/ieee754/dbl-64/e_j1.c +++ b/sysdeps/ieee754/dbl-64/e_j1.c @@ -11,7 +11,7 @@ */ /* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/26, for performance improvement on pipelined processors. -*/ + */ /* __ieee754_j1(x), __ieee754_y1(x) * Bessel function of the first and second kinds of order zero. @@ -61,76 +61,81 @@ #include <math.h> #include <math_private.h> -static double pone(double), qone(double); +static double pone (double), qone (double); static const double -huge = 1e300, -one = 1.0, -invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ -tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ - /* R0/S0 on [0,2] */ -R[] = {-6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */ - 1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */ - -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */ - 4.96727999609584448412e-08}, /* 0x3E6AAAFA, 0x46CA0BD9 */ -S[] = {0.0, 1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */ - 1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */ - 1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */ - 5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */ - 1.23542274426137913908e-11}; /* 0x3DAB2ACF, 0xCFB97ED8 */ + huge = 1e300, + one = 1.0, + invsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ + tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ +/* R0/S0 on [0,2] */ + R[] = { -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */ + 1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */ + -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */ + 4.96727999609584448412e-08 }, /* 0x3E6AAAFA, 0x46CA0BD9 */ + S[] = { 0.0, 1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */ + 1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */ + 1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */ + 5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */ + 1.23542274426137913908e-11 }; /* 0x3DAB2ACF, 0xCFB97ED8 */ -static const double zero = 0.0; +static const double zero = 0.0; double -__ieee754_j1(double x) +__ieee754_j1 (double x) { - double z, s,c,ss,cc,r,u,v,y,r1,r2,s1,s2,s3,z2,z4; - int32_t hx,ix; + double z, s, c, ss, cc, r, u, v, y, r1, r2, s1, s2, s3, z2, z4; + int32_t hx, ix; - GET_HIGH_WORD(hx,x); - ix = hx&0x7fffffff; - if(__builtin_expect(ix>=0x7ff00000, 0)) return one/x; - y = fabs(x); - if(ix >= 0x40000000) { /* |x| >= 2.0 */ - __sincos (y, &s, &c); - ss = -s-c; - cc = s-c; - if(ix<0x7fe00000) { /* make sure y+y not overflow */ - z = __cos(y+y); - if ((s*c)>zero) cc = z/ss; - else ss = z/cc; - } - /* - * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) - * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) - */ - if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrt(y); - else { - u = pone(y); v = qone(y); - z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrt(y); - } - if(hx<0) return -z; - else return z; + GET_HIGH_WORD (hx, x); + ix = hx & 0x7fffffff; + if (__builtin_expect (ix >= 0x7ff00000, 0)) + return one / x; + y = fabs (x); + if (ix >= 0x40000000) /* |x| >= 2.0 */ + { + __sincos (y, &s, &c); + ss = -s - c; + cc = s - c; + if (ix < 0x7fe00000) /* make sure y+y not overflow */ + { + z = __cos (y + y); + if ((s * c) > zero) + cc = z / ss; + else + ss = z / cc; } - if(__builtin_expect(ix<0x3e400000, 0)) { /* |x|<2**-27 */ - if(huge+x>one) return 0.5*x;/* inexact if x!=0 necessary */ + /* + * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) + * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) + */ + if (ix > 0x48000000) + z = (invsqrtpi * cc) / __ieee754_sqrt (y); + else + { + u = pone (y); v = qone (y); + z = invsqrtpi * (u * cc - v * ss) / __ieee754_sqrt (y); } - z = x*x; -#ifdef DO_NOT_USE_THIS - r = z*(r00+z*(r01+z*(r02+z*r03))); - s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); - r *= x; -#else - r1 = z*R[0]; z2=z*z; - r2 = R[1]+z*R[2]; z4=z2*z2; - r = r1 + z2*r2 + z4*R[3]; - r *= x; - s1 = one+z*S[1]; - s2 = S[2]+z*S[3]; - s3 = S[4]+z*S[5]; - s = s1 + z2*s2 + z4*s3; -#endif - return(x*0.5+r/s); + if (hx < 0) + return -z; + else + return z; + } + if (__builtin_expect (ix < 0x3e400000, 0)) /* |x|<2**-27 */ + { + if (huge + x > one) + return 0.5 * x; /* inexact if x!=0 necessary */ + } + z = x * x; + r1 = z * R[0]; z2 = z * z; + r2 = R[1] + z * R[2]; z4 = z2 * z2; + r = r1 + z2 * r2 + z4 * R[3]; + r *= x; + s1 = one + z * S[1]; + s2 = S[2] + z * S[3]; + s3 = S[4] + z * S[5]; + s = s1 + z2 * s2 + z4 * s3; + return (x * 0.5 + r / s); } strong_alias (__ieee754_j1, __j1_finite) @@ -150,62 +155,67 @@ static const double V0[5] = { }; double -__ieee754_y1(double x) +__ieee754_y1 (double x) { - double z, s,c,ss,cc,u,v,u1,u2,v1,v2,v3,z2,z4; - int32_t hx,ix,lx; + double z, s, c, ss, cc, u, v, u1, u2, v1, v2, v3, z2, z4; + int32_t hx, ix, lx; - EXTRACT_WORDS(hx,lx,x); - ix = 0x7fffffff&hx; - /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ - if(__builtin_expect(ix>=0x7ff00000, 0)) return one/(x+x*x); - if(__builtin_expect((ix|lx)==0, 0)) - return -HUGE_VAL+x; /* -inf and overflow exception. */; - if(__builtin_expect(hx<0, 0)) return zero/(zero*x); - if(ix >= 0x40000000) { /* |x| >= 2.0 */ - __sincos (x, &s, &c); - ss = -s-c; - cc = s-c; - if(ix<0x7fe00000) { /* make sure x+x not overflow */ - z = __cos(x+x); - if ((s*c)>zero) cc = z/ss; - else ss = z/cc; - } - /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) - * where x0 = x-3pi/4 - * Better formula: - * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) - * = 1/sqrt(2) * (sin(x) - cos(x)) - * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) - * = -1/sqrt(2) * (cos(x) + sin(x)) - * To avoid cancellation, use - * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) - * to compute the worse one. - */ - if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrt(x); - else { - u = pone(x); v = qone(x); - z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrt(x); - } - return z; + EXTRACT_WORDS (hx, lx, x); + ix = 0x7fffffff & hx; + /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ + if (__builtin_expect (ix >= 0x7ff00000, 0)) + return one / (x + x * x); + if (__builtin_expect ((ix | lx) == 0, 0)) + return -HUGE_VAL + x; + /* -inf and overflow exception. */; + if (__builtin_expect (hx < 0, 0)) + return zero / (zero * x); + if (ix >= 0x40000000) /* |x| >= 2.0 */ + { + __sincos (x, &s, &c); + ss = -s - c; + cc = s - c; + if (ix < 0x7fe00000) /* make sure x+x not overflow */ + { + z = __cos (x + x); + if ((s * c) > zero) + cc = z / ss; + else + ss = z / cc; } - if(__builtin_expect(ix<=0x3c900000, 0)) { /* x < 2**-54 */ - return(-tpi/x); + /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) + * where x0 = x-3pi/4 + * Better formula: + * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = -1/sqrt(2) * (cos(x) + sin(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + if (ix > 0x48000000) + z = (invsqrtpi * ss) / __ieee754_sqrt (x); + else + { + u = pone (x); v = qone (x); + z = invsqrtpi * (u * ss + v * cc) / __ieee754_sqrt (x); } - z = x*x; -#ifdef DO_NOT_USE_THIS - u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); - v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); -#else - u1 = U0[0]+z*U0[1];z2=z*z; - u2 = U0[2]+z*U0[3];z4=z2*z2; - u = u1 + z2*u2 + z4*U0[4]; - v1 = one+z*V0[0]; - v2 = V0[1]+z*V0[2]; - v3 = V0[3]+z*V0[4]; - v = v1 + z2*v2 + z4*v3; -#endif - return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x)); + return z; + } + if (__builtin_expect (ix <= 0x3c900000, 0)) /* x < 2**-54 */ + { + return (-tpi / x); + } + z = x * x; + u1 = U0[0] + z * U0[1]; z2 = z * z; + u2 = U0[2] + z * U0[3]; z4 = z2 * z2; + u = u1 + z2 * u2 + z4 * U0[4]; + v1 = one + z * V0[0]; + v2 = V0[1] + z * V0[2]; + v3 = V0[3] + z * V0[4]; + v = v1 + z2 * v2 + z4 * v3; + return (x * (u / v) + tpi * (__ieee754_j1 (x) * __ieee754_log (x) - one / x)); } strong_alias (__ieee754_y1, __y1_finite) @@ -267,7 +277,7 @@ static const double ps3[5] = { 1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */ }; -static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +static const double pr2[6] = { /* for x in [2.8570,2]=1/[0.3499,0.5] */ 1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */ 1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */ 2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */ @@ -284,33 +294,43 @@ static const double ps2[5] = { }; static double -pone(double x) +pone (double x) { - const double *p,*q; - double z,r,s,r1,r2,r3,s1,s2,s3,z2,z4; - int32_t ix; - GET_HIGH_WORD(ix,x); - ix &= 0x7fffffff; - if (ix>=0x41b00000) {return one;} - else if(ix>=0x40200000){p = pr8; q= ps8;} - else if(ix>=0x40122E8B){p = pr5; q= ps5;} - else if(ix>=0x4006DB6D){p = pr3; q= ps3;} - else if(ix>=0x40000000){p = pr2; q= ps2;} - z = one/(x*x); -#ifdef DO_NOT_USE_THIS - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); -#else - r1 = p[0]+z*p[1]; z2=z*z; - r2 = p[2]+z*p[3]; z4=z2*z2; - r3 = p[4]+z*p[5]; - r = r1 + z2*r2 + z4*r3; - s1 = one+z*q[0]; - s2 = q[1]+z*q[2]; - s3 = q[3]+z*q[4]; - s = s1 + z2*s2 + z4*s3; -#endif - return one+ r/s; + const double *p, *q; + double z, r, s, r1, r2, r3, s1, s2, s3, z2, z4; + int32_t ix; + GET_HIGH_WORD (ix, x); + ix &= 0x7fffffff; + if (ix >= 0x41b00000) + { + return one; + } + else if (ix >= 0x40200000) + { + p = pr8; q = ps8; + } + else if (ix >= 0x40122E8B) + { + p = pr5; q = ps5; + } + else if (ix >= 0x4006DB6D) + { + p = pr3; q = ps3; + } + else if (ix >= 0x40000000) + { + p = pr2; q = ps2; + } + z = one / (x * x); + r1 = p[0] + z * p[1]; z2 = z * z; + r2 = p[2] + z * p[3]; z4 = z2 * z2; + r3 = p[4] + z * p[5]; + r = r1 + z2 * r2 + z4 * r3; + s1 = one + z * q[0]; + s2 = q[1] + z * q[2]; + s3 = q[3] + z * q[4]; + s = s1 + z2 * s2 + z4 * s3; + return one + r / s; } @@ -375,7 +395,7 @@ static const double qs3[6] = { -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */ }; -static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +static const double qr2[6] = { /* for x in [2.8570,2]=1/[0.3499,0.5] */ -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */ -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */ -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */ @@ -393,31 +413,41 @@ static const double qs2[6] = { }; static double -qone(double x) +qone (double x) { - const double *p,*q; - double s,r,z,r1,r2,r3,s1,s2,s3,z2,z4,z6; - int32_t ix; - GET_HIGH_WORD(ix,x); - ix &= 0x7fffffff; - if (ix>=0x41b00000) {return .375/x;} - else if(ix>=0x40200000){p = qr8; q= qs8;} - else if(ix>=0x40122E8B){p = qr5; q= qs5;} - else if(ix>=0x4006DB6D){p = qr3; q= qs3;} - else if(ix>=0x40000000){p = qr2; q= qs2;} - z = one/(x*x); -#ifdef DO_NOT_USE_THIS - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); -#else - r1 = p[0]+z*p[1]; z2=z*z; - r2 = p[2]+z*p[3]; z4=z2*z2; - r3 = p[4]+z*p[5]; z6=z4*z2; - r = r1 + z2*r2 + z4*r3; - s1 = one+z*q[0]; - s2 = q[1]+z*q[2]; - s3 = q[3]+z*q[4]; - s = s1 + z2*s2 + z4*s3 + z6*q[5]; -#endif - return (.375 + r/s)/x; + const double *p, *q; + double s, r, z, r1, r2, r3, s1, s2, s3, z2, z4, z6; + int32_t ix; + GET_HIGH_WORD (ix, x); + ix &= 0x7fffffff; + if (ix >= 0x41b00000) + { + return .375 / x; + } + else if (ix >= 0x40200000) + { + p = qr8; q = qs8; + } + else if (ix >= 0x40122E8B) + { + p = qr5; q = qs5; + } + else if (ix >= 0x4006DB6D) + { + p = qr3; q = qs3; + } + else if (ix >= 0x40000000) + { + p = qr2; q = qs2; + } + z = one / (x * x); + r1 = p[0] + z * p[1]; z2 = z * z; + r2 = p[2] + z * p[3]; z4 = z2 * z2; + r3 = p[4] + z * p[5]; z6 = z4 * z2; + r = r1 + z2 * r2 + z4 * r3; + s1 = one + z * q[0]; + s2 = q[1] + z * q[2]; + s3 = q[3] + z * q[4]; + s = s1 + z2 * s2 + z4 * s3 + z6 * q[5]; + return (.375 + r / s) / x; } diff --git a/sysdeps/ieee754/dbl-64/e_jn.c b/sysdeps/ieee754/dbl-64/e_jn.c index 0d2a24c93b..f48e43a0d9 100644 --- a/sysdeps/ieee754/dbl-64/e_jn.c +++ b/sysdeps/ieee754/dbl-64/e_jn.c @@ -41,246 +41,284 @@ #include <math_private.h> static const double -invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ -two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ -one = 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */ + invsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ + two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ + one = 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */ -static const double zero = 0.00000000000000000000e+00; +static const double zero = 0.00000000000000000000e+00; double -__ieee754_jn(int n, double x) +__ieee754_jn (int n, double x) { - int32_t i,hx,ix,lx, sgn; - double a, b, temp, di; - double z, w; + int32_t i, hx, ix, lx, sgn; + double a, b, temp, di; + double z, w; - /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) - * Thus, J(-n,x) = J(n,-x) - */ - EXTRACT_WORDS(hx,lx,x); - ix = 0x7fffffff&hx; - /* if J(n,NaN) is NaN */ - if(__builtin_expect((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000, 0)) - return x+x; - if(n<0){ - n = -n; - x = -x; - hx ^= 0x80000000; + /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) + * Thus, J(-n,x) = J(n,-x) + */ + EXTRACT_WORDS (hx, lx, x); + ix = 0x7fffffff & hx; + /* if J(n,NaN) is NaN */ + if (__builtin_expect ((ix | ((u_int32_t) (lx | -lx)) >> 31) > 0x7ff00000, 0)) + return x + x; + if (n < 0) + { + n = -n; + x = -x; + hx ^= 0x80000000; + } + if (n == 0) + return (__ieee754_j0 (x)); + if (n == 1) + return (__ieee754_j1 (x)); + sgn = (n & 1) & (hx >> 31); /* even n -- 0, odd n -- sign(x) */ + x = fabs (x); + if (__builtin_expect ((ix | lx) == 0 || ix >= 0x7ff00000, 0)) + /* if x is 0 or inf */ + b = zero; + else if ((double) n <= x) + { + /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ + if (ix >= 0x52D00000) /* x > 2**302 */ + { /* (x >> n**2) + * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Let s=sin(x), c=cos(x), + * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then + * + * n sin(xn)*sqt2 cos(xn)*sqt2 + * ---------------------------------- + * 0 s-c c+s + * 1 -s-c -c+s + * 2 -s+c -c-s + * 3 s+c c-s + */ + double s; + double c; + __sincos (x, &s, &c); + switch (n & 3) + { + case 0: temp = c + s; break; + case 1: temp = -c + s; break; + case 2: temp = -c - s; break; + case 3: temp = c - s; break; + } + b = invsqrtpi * temp / __ieee754_sqrt (x); } - if(n==0) return(__ieee754_j0(x)); - if(n==1) return(__ieee754_j1(x)); - sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */ - x = fabs(x); - if(__builtin_expect((ix|lx)==0||ix>=0x7ff00000,0)) - /* if x is 0 or inf */ - b = zero; - else if((double)n<=x) { - /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ - if(ix>=0x52D00000) { /* x > 2**302 */ - /* (x >> n**2) - * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) - * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) - * Let s=sin(x), c=cos(x), - * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then - * - * n sin(xn)*sqt2 cos(xn)*sqt2 - * ---------------------------------- - * 0 s-c c+s - * 1 -s-c -c+s - * 2 -s+c -c-s - * 3 s+c c-s - */ - double s; - double c; - __sincos (x, &s, &c); - switch(n&3) { - case 0: temp = c + s; break; - case 1: temp = -c + s; break; - case 2: temp = -c - s; break; - case 3: temp = c - s; break; - } - b = invsqrtpi*temp/__ieee754_sqrt(x); - } else { - a = __ieee754_j0(x); - b = __ieee754_j1(x); - for(i=1;i<n;i++){ - temp = b; - b = b*((double)(i+i)/x) - a; /* avoid underflow */ - a = temp; - } + else + { + a = __ieee754_j0 (x); + b = __ieee754_j1 (x); + for (i = 1; i < n; i++) + { + temp = b; + b = b * ((double) (i + i) / x) - a; /* avoid underflow */ + a = temp; } - } else { - if(ix<0x3e100000) { /* x < 2**-29 */ - /* x is tiny, return the first Taylor expansion of J(n,x) - * J(n,x) = 1/n!*(x/2)^n - ... - */ - if(n>33) /* underflow */ - b = zero; - else { - temp = x*0.5; b = temp; - for (a=one,i=2;i<=n;i++) { - a *= (double)i; /* a = n! */ - b *= temp; /* b = (x/2)^n */ - } - b = b/a; + } + } + else + { + if (ix < 0x3e100000) /* x < 2**-29 */ + { /* x is tiny, return the first Taylor expansion of J(n,x) + * J(n,x) = 1/n!*(x/2)^n - ... + */ + if (n > 33) /* underflow */ + b = zero; + else + { + temp = x * 0.5; b = temp; + for (a = one, i = 2; i <= n; i++) + { + a *= (double) i; /* a = n! */ + b *= temp; /* b = (x/2)^n */ } - } else { - /* use backward recurrence */ - /* x x^2 x^2 - * J(n,x)/J(n-1,x) = ---- ------ ------ ..... - * 2n - 2(n+1) - 2(n+2) - * - * 1 1 1 - * (for large x) = ---- ------ ------ ..... - * 2n 2(n+1) 2(n+2) - * -- - ------ - ------ - - * x x x - * - * Let w = 2n/x and h=2/x, then the above quotient - * is equal to the continued fraction: - * 1 - * = ----------------------- - * 1 - * w - ----------------- - * 1 - * w+h - --------- - * w+2h - ... - * - * To determine how many terms needed, let - * Q(0) = w, Q(1) = w(w+h) - 1, - * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), - * When Q(k) > 1e4 good for single - * When Q(k) > 1e9 good for double - * When Q(k) > 1e17 good for quadruple - */ - /* determine k */ - double t,v; - double q0,q1,h,tmp; int32_t k,m; - w = (n+n)/(double)x; h = 2.0/(double)x; - q0 = w; z = w+h; q1 = w*z - 1.0; k=1; - while(q1<1.0e9) { - k += 1; z += h; - tmp = z*q1 - q0; - q0 = q1; - q1 = tmp; + b = b / a; + } + } + else + { + /* use backward recurrence */ + /* x x^2 x^2 + * J(n,x)/J(n-1,x) = ---- ------ ------ ..... + * 2n - 2(n+1) - 2(n+2) + * + * 1 1 1 + * (for large x) = ---- ------ ------ ..... + * 2n 2(n+1) 2(n+2) + * -- - ------ - ------ - + * x x x + * + * Let w = 2n/x and h=2/x, then the above quotient + * is equal to the continued fraction: + * 1 + * = ----------------------- + * 1 + * w - ----------------- + * 1 + * w+h - --------- + * w+2h - ... + * + * To determine how many terms needed, let + * Q(0) = w, Q(1) = w(w+h) - 1, + * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), + * When Q(k) > 1e4 good for single + * When Q(k) > 1e9 good for double + * When Q(k) > 1e17 good for quadruple + */ + /* determine k */ + double t, v; + double q0, q1, h, tmp; int32_t k, m; + w = (n + n) / (double) x; h = 2.0 / (double) x; + q0 = w; z = w + h; q1 = w * z - 1.0; k = 1; + while (q1 < 1.0e9) + { + k += 1; z += h; + tmp = z * q1 - q0; + q0 = q1; + q1 = tmp; + } + m = n + n; + for (t = zero, i = 2 * (n + k); i >= m; i -= 2) + t = one / (i / x - t); + a = t; + b = one; + /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) + * Hence, if n*(log(2n/x)) > ... + * single 8.8722839355e+01 + * double 7.09782712893383973096e+02 + * long double 1.1356523406294143949491931077970765006170e+04 + * then recurrent value may overflow and the result is + * likely underflow to zero + */ + tmp = n; + v = two / x; + tmp = tmp * __ieee754_log (fabs (v * tmp)); + if (tmp < 7.09782712893383973096e+02) + { + for (i = n - 1, di = (double) (i + i); i > 0; i--) + { + temp = b; + b *= di; + b = b / x - a; + a = temp; + di -= two; } - m = n+n; - for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t); - a = t; - b = one; - /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) - * Hence, if n*(log(2n/x)) > ... - * single 8.8722839355e+01 - * double 7.09782712893383973096e+02 - * long double 1.1356523406294143949491931077970765006170e+04 - * then recurrent value may overflow and the result is - * likely underflow to zero - */ - tmp = n; - v = two/x; - tmp = tmp*__ieee754_log(fabs(v*tmp)); - if(tmp<7.09782712893383973096e+02) { - for(i=n-1,di=(double)(i+i);i>0;i--){ - temp = b; - b *= di; - b = b/x - a; - a = temp; - di -= two; - } - } else { - for(i=n-1,di=(double)(i+i);i>0;i--){ - temp = b; - b *= di; - b = b/x - a; - a = temp; - di -= two; - /* scale b to avoid spurious overflow */ - if(b>1e100) { - a /= b; - t /= b; - b = one; - } + } + else + { + for (i = n - 1, di = (double) (i + i); i > 0; i--) + { + temp = b; + b *= di; + b = b / x - a; + a = temp; + di -= two; + /* scale b to avoid spurious overflow */ + if (b > 1e100) + { + a /= b; + t /= b; + b = one; } } - /* j0() and j1() suffer enormous loss of precision at and - * near zero; however, we know that their zero points never - * coincide, so just choose the one further away from zero. - */ - z = __ieee754_j0 (x); - w = __ieee754_j1 (x); - if (fabs (z) >= fabs (w)) - b = (t * z / b); - else - b = (t * w / a); } + /* j0() and j1() suffer enormous loss of precision at and + * near zero; however, we know that their zero points never + * coincide, so just choose the one further away from zero. + */ + z = __ieee754_j0 (x); + w = __ieee754_j1 (x); + if (fabs (z) >= fabs (w)) + b = (t * z / b); + else + b = (t * w / a); } - if(sgn==1) return -b; else return b; + } + if (sgn == 1) + return -b; + else + return b; } strong_alias (__ieee754_jn, __jn_finite) double -__ieee754_yn(int n, double x) +__ieee754_yn (int n, double x) { - int32_t i,hx,ix,lx; - int32_t sign; - double a, b, temp; + int32_t i, hx, ix, lx; + int32_t sign; + double a, b, temp; - EXTRACT_WORDS(hx,lx,x); - ix = 0x7fffffff&hx; - /* if Y(n,NaN) is NaN */ - if(__builtin_expect((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000,0)) - return x+x; - if(__builtin_expect((ix|lx)==0, 0)) - return -HUGE_VAL+x; /* -inf and overflow exception. */; - if(__builtin_expect(hx<0, 0)) return zero/(zero*x); - sign = 1; - if(n<0){ - n = -n; - sign = 1 - ((n&1)<<1); + EXTRACT_WORDS (hx, lx, x); + ix = 0x7fffffff & hx; + /* if Y(n,NaN) is NaN */ + if (__builtin_expect ((ix | ((u_int32_t) (lx | -lx)) >> 31) > 0x7ff00000, 0)) + return x + x; + if (__builtin_expect ((ix | lx) == 0, 0)) + return -HUGE_VAL + x; + /* -inf and overflow exception. */; + if (__builtin_expect (hx < 0, 0)) + return zero / (zero * x); + sign = 1; + if (n < 0) + { + n = -n; + sign = 1 - ((n & 1) << 1); + } + if (n == 0) + return (__ieee754_y0 (x)); + if (n == 1) + return (sign * __ieee754_y1 (x)); + if (__builtin_expect (ix == 0x7ff00000, 0)) + return zero; + if (ix >= 0x52D00000) /* x > 2**302 */ + { /* (x >> n**2) + * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Let s=sin(x), c=cos(x), + * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then + * + * n sin(xn)*sqt2 cos(xn)*sqt2 + * ---------------------------------- + * 0 s-c c+s + * 1 -s-c -c+s + * 2 -s+c -c-s + * 3 s+c c-s + */ + double c; + double s; + __sincos (x, &s, &c); + switch (n & 3) + { + case 0: temp = s - c; break; + case 1: temp = -s - c; break; + case 2: temp = -s + c; break; + case 3: temp = s + c; break; } - if(n==0) return(__ieee754_y0(x)); - if(n==1) return(sign*__ieee754_y1(x)); - if(__builtin_expect(ix==0x7ff00000, 0)) return zero; - if(ix>=0x52D00000) { /* x > 2**302 */ - /* (x >> n**2) - * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) - * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) - * Let s=sin(x), c=cos(x), - * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then - * - * n sin(xn)*sqt2 cos(xn)*sqt2 - * ---------------------------------- - * 0 s-c c+s - * 1 -s-c -c+s - * 2 -s+c -c-s - * 3 s+c c-s - */ - double c; - double s; - __sincos (x, &s, &c); - switch(n&3) { - case 0: temp = s - c; break; - case 1: temp = -s - c; break; - case 2: temp = -s + c; break; - case 3: temp = s + c; break; - } - b = invsqrtpi*temp/__ieee754_sqrt(x); - } else { - u_int32_t high; - a = __ieee754_y0(x); - b = __ieee754_y1(x); - /* quit if b is -inf */ - GET_HIGH_WORD(high,b); - for(i=1;i<n&&high!=0xfff00000;i++){ - temp = b; - b = ((double)(i+i)/x)*b - a; - GET_HIGH_WORD(high,b); - a = temp; - } - /* If B is +-Inf, set up errno accordingly. */ - if (! __finite (b)) - __set_errno (ERANGE); + b = invsqrtpi * temp / __ieee754_sqrt (x); + } + else + { + u_int32_t high; + a = __ieee754_y0 (x); + b = __ieee754_y1 (x); + /* quit if b is -inf */ + GET_HIGH_WORD (high, b); + for (i = 1; i < n && high != 0xfff00000; i++) + { + temp = b; + b = ((double) (i + i) / x) * b - a; + GET_HIGH_WORD (high, b); + a = temp; } - if(sign>0) return b; else return -b; + /* If B is +-Inf, set up errno accordingly. */ + if (!__finite (b)) + __set_errno (ERANGE); + } + if (sign > 0) + return b; + else + return -b; } strong_alias (__ieee754_yn, __yn_finite) diff --git a/sysdeps/ieee754/dbl-64/e_log.c b/sysdeps/ieee754/dbl-64/e_log.c index f9300f9cef..a7ab544354 100644 --- a/sysdeps/ieee754/dbl-64/e_log.c +++ b/sysdeps/ieee754/dbl-64/e_log.c @@ -39,6 +39,7 @@ #include "mpa.h" #include "MathLib.h" #include <math_private.h> +#include <stap-probe.h> #ifndef SECTION # define SECTION @@ -55,12 +56,12 @@ SECTION __ieee754_log (double x) { #define M 4 - static const int pr[M] = {8, 10, 18, 32}; + static const int pr[M] = { 8, 10, 18, 32 }; int i, j, n, ux, dx, p; double dbl_n, u, p0, q, r0, w, nln2a, luai, lubi, lvaj, lvbj, - sij, ssij, ttij, A, B, B0, y, y1, y2, polI, polII, sa, sb, - t1, t2, t7, t8, t, ra, rb, ww, - a0, aa0, s1, s2, ss2, s3, ss3, a1, aa1, a, aa, b, bb, c; + sij, ssij, ttij, A, B, B0, y, y1, y2, polI, polII, sa, sb, + t1, t2, t7, t8, t, ra, rb, ww, + a0, aa0, s1, s2, ss2, s3, ss3, a1, aa1, a, aa, b, bb, c; #ifndef DLA_FMS double t3, t4, t5, t6; #endif @@ -79,15 +80,15 @@ __ieee754_log (double x) if (__builtin_expect (ux < 0x00100000, 0)) { if (__builtin_expect (((ux & 0x7fffffff) | dx) == 0, 0)) - return MHALF / 0.0; /* return -INF */ + return MHALF / 0.0; /* return -INF */ if (__builtin_expect (ux < 0, 0)) - return (x - x) / 0.0; /* return NaN */ + return (x - x) / 0.0; /* return NaN */ n -= 54; - x *= two54.d; /* scale x */ + x *= two54.d; /* scale x */ num.d = x; } if (__builtin_expect (ux >= 0x7ff00000, 0)) - return x + x; /* INF or NaN */ + return x + x; /* INF or NaN */ /* Regular values of x */ @@ -242,8 +243,12 @@ stage_n: __mp_dbl (&mpy1, &y1, p); __mp_dbl (&mpy2, &y2, p); if (y1 == y2) - return y1; + { + LIBC_PROBE (slowlog, 3, &p, &x, &y1); + return y1; + } } + LIBC_PROBE (slowlog_inexact, 3, &p, &x, &y1); return y1; } diff --git a/sysdeps/ieee754/dbl-64/e_log10.c b/sysdeps/ieee754/dbl-64/e_log10.c index ab5069e58e..c3d465a4a9 100644 --- a/sysdeps/ieee754/dbl-64/e_log10.c +++ b/sysdeps/ieee754/dbl-64/e_log10.c @@ -46,10 +46,10 @@ #include <math.h> #include <math_private.h> -static const double two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ -static const double ivln10 = 4.34294481903251816668e-01; /* 0x3FDBCB7B, 0x1526E50E */ -static const double log10_2hi = 3.01029995663611771306e-01; /* 0x3FD34413, 0x509F6000 */ -static const double log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ +static const double two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ +static const double ivln10 = 4.34294481903251816668e-01; /* 0x3FDBCB7B, 0x1526E50E */ +static const double log10_2hi = 3.01029995663611771306e-01; /* 0x3FD34413, 0x509F6000 */ +static const double log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ double __ieee754_log10 (double x) @@ -62,13 +62,13 @@ __ieee754_log10 (double x) k = 0; if (hx < 0x00100000) - { /* x < 2**-1022 */ + { /* x < 2**-1022 */ if (__builtin_expect (((hx & 0x7fffffff) | lx) == 0, 0)) - return -two54 / (x - x); /* log(+-0)=-inf */ + return -two54 / (x - x); /* log(+-0)=-inf */ if (__builtin_expect (hx < 0, 0)) - return (x - x) / (x - x); /* log(-#) = NaN */ + return (x - x) / (x - x); /* log(-#) = NaN */ k -= 54; - x *= two54; /* subnormal number, scale up x */ + x *= two54; /* subnormal number, scale up x */ GET_HIGH_WORD (hx, x); } if (__builtin_expect (hx >= 0x7ff00000, 0)) diff --git a/sysdeps/ieee754/dbl-64/e_log2.c b/sysdeps/ieee754/dbl-64/e_log2.c index 4d5cab0ed3..890a4a2bd0 100644 --- a/sysdeps/ieee754/dbl-64/e_log2.c +++ b/sysdeps/ieee754/dbl-64/e_log2.c @@ -58,14 +58,14 @@ #include <math_private.h> static const double ln2 = 0.69314718055994530942; -static const double two54 = 1.80143985094819840000e+16; /* 43500000 00000000 */ -static const double Lg1 = 6.666666666666735130e-01; /* 3FE55555 55555593 */ -static const double Lg2 = 3.999999999940941908e-01; /* 3FD99999 9997FA04 */ -static const double Lg3 = 2.857142874366239149e-01; /* 3FD24924 94229359 */ -static const double Lg4 = 2.222219843214978396e-01; /* 3FCC71C5 1D8E78AF */ -static const double Lg5 = 1.818357216161805012e-01; /* 3FC74664 96CB03DE */ -static const double Lg6 = 1.531383769920937332e-01; /* 3FC39A09 D078C69F */ -static const double Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ +static const double two54 = 1.80143985094819840000e+16; /* 43500000 00000000 */ +static const double Lg1 = 6.666666666666735130e-01; /* 3FE55555 55555593 */ +static const double Lg2 = 3.999999999940941908e-01; /* 3FD99999 9997FA04 */ +static const double Lg3 = 2.857142874366239149e-01; /* 3FD24924 94229359 */ +static const double Lg4 = 2.222219843214978396e-01; /* 3FCC71C5 1D8E78AF */ +static const double Lg5 = 1.818357216161805012e-01; /* 3FC74664 96CB03DE */ +static const double Lg6 = 1.531383769920937332e-01; /* 3FC39A09 D078C69F */ +static const double Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ static const double zero = 0.0; @@ -80,13 +80,13 @@ __ieee754_log2 (double x) k = 0; if (hx < 0x00100000) - { /* x < 2**-1022 */ + { /* x < 2**-1022 */ if (__builtin_expect (((hx & 0x7fffffff) | lx) == 0, 0)) - return -two54 / (x - x); /* log(+-0)=-inf */ + return -two54 / (x - x); /* log(+-0)=-inf */ if (__builtin_expect (hx < 0, 0)) - return (x - x) / (x - x); /* log(-#) = NaN */ + return (x - x) / (x - x); /* log(-#) = NaN */ k -= 54; - x *= two54; /* subnormal number, scale up x */ + x *= two54; /* subnormal number, scale up x */ GET_HIGH_WORD (hx, x); } if (__builtin_expect (hx >= 0x7ff00000, 0)) @@ -94,12 +94,12 @@ __ieee754_log2 (double x) k += (hx >> 20) - 1023; hx &= 0x000fffff; i = (hx + 0x95f64) & 0x100000; - SET_HIGH_WORD (x, hx | (i ^ 0x3ff00000)); /* normalize x or x/2 */ + SET_HIGH_WORD (x, hx | (i ^ 0x3ff00000)); /* normalize x or x/2 */ k += (i >> 20); dk = (double) k; f = x - 1.0; if ((0x000fffff & (2 + hx)) < 3) - { /* |f| < 2**-20 */ + { /* |f| < 2**-20 */ if (f == zero) return dk; R = f * f * (0.5 - 0.33333333333333333 * f); diff --git a/sysdeps/ieee754/dbl-64/e_pow.c b/sysdeps/ieee754/dbl-64/e_pow.c index 9a766e7224..9cf2309174 100644 --- a/sysdeps/ieee754/dbl-64/e_pow.c +++ b/sysdeps/ieee754/dbl-64/e_pow.c @@ -49,354 +49,407 @@ static const double huge = 1.0e300, tiny = 1.0e-300; -double __exp1(double x, double xx, double error); -static double log1(double x, double *delta, double *error); -static double my_log2(double x, double *delta, double *error); -double __slowpow(double x, double y,double z); -static double power1(double x, double y); -static int checkint(double x); +double __exp1 (double x, double xx, double error); +static double log1 (double x, double *delta, double *error); +static double my_log2 (double x, double *delta, double *error); +double __slowpow (double x, double y, double z); +static double power1 (double x, double y); +static int checkint (double x); -/***************************************************************************/ -/* An ultimate power routine. Given two IEEE double machine numbers y,x */ -/* it computes the correctly rounded (to nearest) value of X^y. */ -/***************************************************************************/ +/* An ultimate power routine. Given two IEEE double machine numbers y, x it + computes the correctly rounded (to nearest) value of X^y. */ double SECTION -__ieee754_pow(double x, double y) { - double z,a,aa,error, t,a1,a2,y1,y2; - mynumber u,v; +__ieee754_pow (double x, double y) +{ + double z, a, aa, error, t, a1, a2, y1, y2; + mynumber u, v; int k; - int4 qx,qy; - v.x=y; - u.x=x; - if (v.i[LOW_HALF] == 0) { /* of y */ - qx = u.i[HIGH_HALF]&0x7fffffff; - /* Is x a NaN? */ - if (((qx == 0x7ff00000) && (u.i[LOW_HALF] != 0)) || (qx > 0x7ff00000)) - return x; - if (y == 1.0) return x; - if (y == 2.0) return x*x; - if (y == -1.0) return 1.0/x; - if (y == 0) return 1.0; - } + int4 qx, qy; + v.x = y; + u.x = x; + if (v.i[LOW_HALF] == 0) + { /* of y */ + qx = u.i[HIGH_HALF] & 0x7fffffff; + /* Is x a NaN? */ + if (((qx == 0x7ff00000) && (u.i[LOW_HALF] != 0)) || (qx > 0x7ff00000)) + return x; + if (y == 1.0) + return x; + if (y == 2.0) + return x * x; + if (y == -1.0) + return 1.0 / x; + if (y == 0) + return 1.0; + } /* else */ - if(((u.i[HIGH_HALF]>0 && u.i[HIGH_HALF]<0x7ff00000)|| /* x>0 and not x->0 */ - (u.i[HIGH_HALF]==0 && u.i[LOW_HALF]!=0)) && - /* 2^-1023< x<= 2^-1023 * 0x1.0000ffffffff */ - (v.i[HIGH_HALF]&0x7fffffff) < 0x4ff00000) { /* if y<-1 or y>1 */ - double retval; + if (((u.i[HIGH_HALF] > 0 && u.i[HIGH_HALF] < 0x7ff00000) || /* x>0 and not x->0 */ + (u.i[HIGH_HALF] == 0 && u.i[LOW_HALF] != 0)) && + /* 2^-1023< x<= 2^-1023 * 0x1.0000ffffffff */ + (v.i[HIGH_HALF] & 0x7fffffff) < 0x4ff00000) + { /* if y<-1 or y>1 */ + double retval; - SET_RESTORE_ROUND (FE_TONEAREST); + SET_RESTORE_ROUND (FE_TONEAREST); - /* Avoid internal underflow for tiny y. The exact value of y does - not matter if |y| <= 2**-64. */ - if (ABS (y) < 0x1p-64) - y = y < 0 ? -0x1p-64 : 0x1p-64; - z = log1(x,&aa,&error); /* x^y =e^(y log (X)) */ - t = y*CN; - y1 = t - (t-y); - y2 = y - y1; - t = z*CN; - a1 = t - (t-z); - a2 = (z - a1)+aa; - a = y1*a1; - aa = y2*a1 + y*a2; - a1 = a+aa; - a2 = (a-a1)+aa; - error = error*ABS(y); - t = __exp1(a1,a2,1.9e16*error); /* return -10 or 0 if wasn't computed exactly */ - retval = (t>0)?t:power1(x,y); + /* Avoid internal underflow for tiny y. The exact value of y does + not matter if |y| <= 2**-64. */ + if (ABS (y) < 0x1p-64) + y = y < 0 ? -0x1p-64 : 0x1p-64; + z = log1 (x, &aa, &error); /* x^y =e^(y log (X)) */ + t = y * CN; + y1 = t - (t - y); + y2 = y - y1; + t = z * CN; + a1 = t - (t - z); + a2 = (z - a1) + aa; + a = y1 * a1; + aa = y2 * a1 + y * a2; + a1 = a + aa; + a2 = (a - a1) + aa; + error = error * ABS (y); + t = __exp1 (a1, a2, 1.9e16 * error); /* return -10 or 0 if wasn't computed exactly */ + retval = (t > 0) ? t : power1 (x, y); - return retval; - } + return retval; + } - if (x == 0) { - if (((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] != 0) - || (v.i[HIGH_HALF] & 0x7fffffff) > 0x7ff00000) /* NaN */ - return y; - if (ABS(y) > 1.0e20) return (y>0)?0:1.0/0.0; - k = checkint(y); - if (k == -1) - return y < 0 ? 1.0/x : x; - else - return y < 0 ? 1.0/0.0 : 0.0; /* return 0 */ - } + if (x == 0) + { + if (((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] != 0) + || (v.i[HIGH_HALF] & 0x7fffffff) > 0x7ff00000) /* NaN */ + return y; + if (ABS (y) > 1.0e20) + return (y > 0) ? 0 : 1.0 / 0.0; + k = checkint (y); + if (k == -1) + return y < 0 ? 1.0 / x : x; + else + return y < 0 ? 1.0 / 0.0 : 0.0; /* return 0 */ + } - qx = u.i[HIGH_HALF]&0x7fffffff; /* no sign */ - qy = v.i[HIGH_HALF]&0x7fffffff; /* no sign */ + qx = u.i[HIGH_HALF] & 0x7fffffff; /* no sign */ + qy = v.i[HIGH_HALF] & 0x7fffffff; /* no sign */ - if (qx >= 0x7ff00000 && (qx > 0x7ff00000 || u.i[LOW_HALF] != 0)) /* NaN */ + if (qx >= 0x7ff00000 && (qx > 0x7ff00000 || u.i[LOW_HALF] != 0)) /* NaN */ return x; - if (qy >= 0x7ff00000 && (qy > 0x7ff00000 || v.i[LOW_HALF] != 0)) /* NaN */ + if (qy >= 0x7ff00000 && (qy > 0x7ff00000 || v.i[LOW_HALF] != 0)) /* NaN */ return x == 1.0 ? 1.0 : y; /* if x<0 */ - if (u.i[HIGH_HALF] < 0) { - k = checkint(y); - if (k==0) { - if (qy == 0x7ff00000) { - if (x == -1.0) return 1.0; - else if (x > -1.0) return v.i[HIGH_HALF] < 0 ? INF.x : 0.0; - else return v.i[HIGH_HALF] < 0 ? 0.0 : INF.x; - } + if (u.i[HIGH_HALF] < 0) + { + k = checkint (y); + if (k == 0) + { + if (qy == 0x7ff00000) + { + if (x == -1.0) + return 1.0; + else if (x > -1.0) + return v.i[HIGH_HALF] < 0 ? INF.x : 0.0; + else + return v.i[HIGH_HALF] < 0 ? 0.0 : INF.x; + } + else if (qx == 0x7ff00000) + return y < 0 ? 0.0 : INF.x; + return (x - x) / (x - x); /* y not integer and x<0 */ + } else if (qx == 0x7ff00000) - return y < 0 ? 0.0 : INF.x; - return (x - x) / (x - x); /* y not integer and x<0 */ + { + if (k < 0) + return y < 0 ? nZERO.x : nINF.x; + else + return y < 0 ? 0.0 : INF.x; + } + /* if y even or odd */ + return (k == 1) ? __ieee754_pow (-x, y) : -__ieee754_pow (-x, y); } - else if (qx == 0x7ff00000) - { - if (k < 0) - return y < 0 ? nZERO.x : nINF.x; - else - return y < 0 ? 0.0 : INF.x; - } - return (k==1)?__ieee754_pow(-x,y):-__ieee754_pow(-x,y); /* if y even or odd */ - } /* x>0 */ - if (qx == 0x7ff00000) /* x= 2^-0x3ff */ + if (qx == 0x7ff00000) /* x= 2^-0x3ff */ return y > 0 ? x : 0; - if (qy > 0x45f00000 && qy < 0x7ff00000) { - if (x == 1.0) return 1.0; - if (y>0) return (x>1.0)?huge*huge:tiny*tiny; - if (y<0) return (x<1.0)?huge*huge:tiny*tiny; - } + if (qy > 0x45f00000 && qy < 0x7ff00000) + { + if (x == 1.0) + return 1.0; + if (y > 0) + return (x > 1.0) ? huge * huge : tiny * tiny; + if (y < 0) + return (x < 1.0) ? huge * huge : tiny * tiny; + } - if (x == 1.0) return 1.0; - if (y>0) return (x>1.0)?INF.x:0; - if (y<0) return (x<1.0)?INF.x:0; - return 0; /* unreachable, to make the compiler happy */ + if (x == 1.0) + return 1.0; + if (y > 0) + return (x > 1.0) ? INF.x : 0; + if (y < 0) + return (x < 1.0) ? INF.x : 0; + return 0; /* unreachable, to make the compiler happy */ } + #ifndef __ieee754_pow strong_alias (__ieee754_pow, __pow_finite) #endif -/**************************************************************************/ -/* Computing x^y using more accurate but more slow log routine */ -/**************************************************************************/ +/* Compute x^y using more accurate but more slow log routine. */ static double SECTION -power1(double x, double y) { - double z,a,aa,error, t,a1,a2,y1,y2; - z = my_log2(x,&aa,&error); - t = y*CN; - y1 = t - (t-y); +power1 (double x, double y) +{ + double z, a, aa, error, t, a1, a2, y1, y2; + z = my_log2 (x, &aa, &error); + t = y * CN; + y1 = t - (t - y); y2 = y - y1; - t = z*CN; - a1 = t - (t-z); + t = z * CN; + a1 = t - (t - z); a2 = z - a1; - a = y*z; - aa = ((y1*a1-a)+y1*a2+y2*a1)+y2*a2+aa*y; - a1 = a+aa; - a2 = (a-a1)+aa; - error = error*ABS(y); - t = __exp1(a1,a2,1.9e16*error); - return (t >= 0)?t:__slowpow(x,y,z); + a = y * z; + aa = ((y1 * a1 - a) + y1 * a2 + y2 * a1) + y2 * a2 + aa * y; + a1 = a + aa; + a2 = (a - a1) + aa; + error = error * ABS (y); + t = __exp1 (a1, a2, 1.9e16 * error); + return (t >= 0) ? t : __slowpow (x, y, z); } -/****************************************************************************/ -/* Computing log(x) (x is left argument). The result is the returned double */ -/* + the parameter delta. */ -/* The result is bounded by error (rightmost argument) */ -/****************************************************************************/ +/* Compute log(x) (x is left argument). The result is the returned double + the + parameter DELTA. The result is bounded by ERROR. */ static double SECTION -log1(double x, double *delta, double *error) { - int i,j,m; - double uu,vv,eps,nx,e,e1,e2,t,t1,t2,res,add=0; - mynumber u,v; +log1 (double x, double *delta, double *error) +{ + int i, j, m; + double uu, vv, eps, nx, e, e1, e2, t, t1, t2, res, add = 0; + mynumber u, v; #ifdef BIG_ENDI - mynumber -/**/ two52 = {{0x43300000, 0x00000000}}; /* 2**52 */ + mynumber /**/ two52 = {{0x43300000, 0x00000000}}; /* 2**52 */ #else -#ifdef LITTLE_ENDI - mynumber -/**/ two52 = {{0x00000000, 0x43300000}}; /* 2**52 */ -#endif +# ifdef LITTLE_ENDI + mynumber /**/ two52 = {{0x00000000, 0x43300000}}; /* 2**52 */ +# endif #endif u.x = x; m = u.i[HIGH_HALF]; *error = 0; *delta = 0; - if (m < 0x00100000) /* 1<x<2^-1007 */ - { x = x*t52.x; add = -52.0; u.x = x; m = u.i[HIGH_HALF];} + if (m < 0x00100000) /* 1<x<2^-1007 */ + { + x = x * t52.x; + add = -52.0; + u.x = x; + m = u.i[HIGH_HALF]; + } - if ((m&0x000fffff) < 0x0006a09e) - {u.i[HIGH_HALF] = (m&0x000fffff)|0x3ff00000; two52.i[LOW_HALF]=(m>>20); } + if ((m & 0x000fffff) < 0x0006a09e) + { + u.i[HIGH_HALF] = (m & 0x000fffff) | 0x3ff00000; + two52.i[LOW_HALF] = (m >> 20); + } else - {u.i[HIGH_HALF] = (m&0x000fffff)|0x3fe00000; two52.i[LOW_HALF]=(m>>20)+1; } + { + u.i[HIGH_HALF] = (m & 0x000fffff) | 0x3fe00000; + two52.i[LOW_HALF] = (m >> 20) + 1; + } v.x = u.x + bigu.x; uu = v.x - bigu.x; - i = (v.i[LOW_HALF]&0x000003ff)<<2; - if (two52.i[LOW_HALF] == 1023) /* nx = 0 */ - { - if (i > 1192 && i < 1208) /* |x-1| < 1.5*2**-10 */ - { + i = (v.i[LOW_HALF] & 0x000003ff) << 2; + if (two52.i[LOW_HALF] == 1023) /* nx = 0 */ + { + if (i > 1192 && i < 1208) /* |x-1| < 1.5*2**-10 */ + { t = x - 1.0; - t1 = (t+5.0e6)-5.0e6; - t2 = t-t1; - e1 = t - 0.5*t1*t1; - e2 = t*t*t*(r3+t*(r4+t*(r5+t*(r6+t*(r7+t*r8)))))-0.5*t2*(t+t1); - res = e1+e2; - *error = 1.0e-21*ABS(t); - *delta = (e1-res)+e2; + t1 = (t + 5.0e6) - 5.0e6; + t2 = t - t1; + e1 = t - 0.5 * t1 * t1; + e2 = (t * t * t * (r3 + t * (r4 + t * (r5 + t * (r6 + t + * (r7 + t * r8))))) + - 0.5 * t2 * (t + t1)); + res = e1 + e2; + *error = 1.0e-21 * ABS (t); + *delta = (e1 - res) + e2; return res; - } /* |x-1| < 1.5*2**-10 */ + } /* |x-1| < 1.5*2**-10 */ else - { - v.x = u.x*(ui.x[i]+ui.x[i+1])+bigv.x; - vv = v.x-bigv.x; - j = v.i[LOW_HALF]&0x0007ffff; - j = j+j+j; - eps = u.x - uu*vv; - e1 = eps*ui.x[i]; - e2 = eps*(ui.x[i+1]+vj.x[j]*(ui.x[i]+ui.x[i+1])); - e = e1+e2; - e2 = ((e1-e)+e2); - t=ui.x[i+2]+vj.x[j+1]; - t1 = t+e; - t2 = (((t-t1)+e)+(ui.x[i+3]+vj.x[j+2]))+e2+e*e*(p2+e*(p3+e*p4)); - res=t1+t2; + { + v.x = u.x * (ui.x[i] + ui.x[i + 1]) + bigv.x; + vv = v.x - bigv.x; + j = v.i[LOW_HALF] & 0x0007ffff; + j = j + j + j; + eps = u.x - uu * vv; + e1 = eps * ui.x[i]; + e2 = eps * (ui.x[i + 1] + vj.x[j] * (ui.x[i] + ui.x[i + 1])); + e = e1 + e2; + e2 = ((e1 - e) + e2); + t = ui.x[i + 2] + vj.x[j + 1]; + t1 = t + e; + t2 = ((((t - t1) + e) + (ui.x[i + 3] + vj.x[j + 2])) + e2 + e * e + * (p2 + e * (p3 + e * p4))); + res = t1 + t2; *error = 1.0e-24; - *delta = (t1-res)+t2; + *delta = (t1 - res) + t2; return res; - } - } /* nx = 0 */ - else /* nx != 0 */ - { + } + } /* nx = 0 */ + else /* nx != 0 */ + { eps = u.x - uu; - nx = (two52.x - two52e.x)+add; - e1 = eps*ui.x[i]; - e2 = eps*ui.x[i+1]; - e=e1+e2; - e2 = (e1-e)+e2; - t=nx*ln2a.x+ui.x[i+2]; - t1=t+e; - t2=(((t-t1)+e)+nx*ln2b.x+ui.x[i+3]+e2)+e*e*(q2+e*(q3+e*(q4+e*(q5+e*q6)))); - res = t1+t2; + nx = (two52.x - two52e.x) + add; + e1 = eps * ui.x[i]; + e2 = eps * ui.x[i + 1]; + e = e1 + e2; + e2 = (e1 - e) + e2; + t = nx * ln2a.x + ui.x[i + 2]; + t1 = t + e; + t2 = ((((t - t1) + e) + nx * ln2b.x + ui.x[i + 3] + e2) + e * e + * (q2 + e * (q3 + e * (q4 + e * (q5 + e * q6))))); + res = t1 + t2; *error = 1.0e-21; - *delta = (t1-res)+t2; + *delta = (t1 - res) + t2; return res; - } /* nx != 0 */ + } /* nx != 0 */ } -/****************************************************************************/ -/* More slow but more accurate routine of log */ -/* Computing log(x)(x is left argument).The result is return double + delta.*/ -/* The result is bounded by error (right argument) */ -/****************************************************************************/ +/* Slower but more accurate routine of log. The returned result is double + + DELTA. The result is bounded by ERROR. */ static double SECTION -my_log2(double x, double *delta, double *error) { - int i,j,m; - double uu,vv,eps,nx,e,e1,e2,t,t1,t2,res,add=0; - double ou1,ou2,lu1,lu2,ov,lv1,lv2,a,a1,a2; - double y,yy,z,zz,j1,j2,j7,j8; +my_log2 (double x, double *delta, double *error) +{ + int i, j, m; + double uu, vv, eps, nx, e, e1, e2, t, t1, t2, res, add = 0; + double ou1, ou2, lu1, lu2, ov, lv1, lv2, a, a1, a2; + double y, yy, z, zz, j1, j2, j7, j8; #ifndef DLA_FMS - double j3,j4,j5,j6; + double j3, j4, j5, j6; #endif - mynumber u,v; + mynumber u, v; #ifdef BIG_ENDI - mynumber -/**/ two52 = {{0x43300000, 0x00000000}}; /* 2**52 */ + mynumber /**/ two52 = {{0x43300000, 0x00000000}}; /* 2**52 */ #else -#ifdef LITTLE_ENDI - mynumber -/**/ two52 = {{0x00000000, 0x43300000}}; /* 2**52 */ -#endif +# ifdef LITTLE_ENDI + mynumber /**/ two52 = {{0x00000000, 0x43300000}}; /* 2**52 */ +# endif #endif u.x = x; m = u.i[HIGH_HALF]; *error = 0; *delta = 0; - add=0; - if (m<0x00100000) { /* x < 2^-1022 */ - x = x*t52.x; add = -52.0; u.x = x; m = u.i[HIGH_HALF]; } + add = 0; + if (m < 0x00100000) + { /* x < 2^-1022 */ + x = x * t52.x; + add = -52.0; + u.x = x; + m = u.i[HIGH_HALF]; + } - if ((m&0x000fffff) < 0x0006a09e) - {u.i[HIGH_HALF] = (m&0x000fffff)|0x3ff00000; two52.i[LOW_HALF]=(m>>20); } + if ((m & 0x000fffff) < 0x0006a09e) + { + u.i[HIGH_HALF] = (m & 0x000fffff) | 0x3ff00000; + two52.i[LOW_HALF] = (m >> 20); + } else - {u.i[HIGH_HALF] = (m&0x000fffff)|0x3fe00000; two52.i[LOW_HALF]=(m>>20)+1; } + { + u.i[HIGH_HALF] = (m & 0x000fffff) | 0x3fe00000; + two52.i[LOW_HALF] = (m >> 20) + 1; + } v.x = u.x + bigu.x; uu = v.x - bigu.x; - i = (v.i[LOW_HALF]&0x000003ff)<<2; + i = (v.i[LOW_HALF] & 0x000003ff) << 2; /*------------------------------------- |x-1| < 2**-11------------------------------- */ - if ((two52.i[LOW_HALF] == 1023) && (i == 1200)) - { + if ((two52.i[LOW_HALF] == 1023) && (i == 1200)) + { t = x - 1.0; - EMULV(t,s3,y,yy,j1,j2,j3,j4,j5); - ADD2(-0.5,0,y,yy,z,zz,j1,j2); - MUL2(t,0,z,zz,y,yy,j1,j2,j3,j4,j5,j6,j7,j8); - MUL2(t,0,y,yy,z,zz,j1,j2,j3,j4,j5,j6,j7,j8); + EMULV (t, s3, y, yy, j1, j2, j3, j4, j5); + ADD2 (-0.5, 0, y, yy, z, zz, j1, j2); + MUL2 (t, 0, z, zz, y, yy, j1, j2, j3, j4, j5, j6, j7, j8); + MUL2 (t, 0, y, yy, z, zz, j1, j2, j3, j4, j5, j6, j7, j8); - e1 = t+z; - e2 = (((t-e1)+z)+zz)+t*t*t*(ss3+t*(s4+t*(s5+t*(s6+t*(s7+t*s8))))); - res = e1+e2; - *error = 1.0e-25*ABS(t); - *delta = (e1-res)+e2; + e1 = t + z; + e2 = ((((t - e1) + z) + zz) + t * t * t + * (ss3 + t * (s4 + t * (s5 + t * (s6 + t * (s7 + t * s8)))))); + res = e1 + e2; + *error = 1.0e-25 * ABS (t); + *delta = (e1 - res) + e2; return res; - } + } /*----------------------------- |x-1| > 2**-11 -------------------------- */ else - { /*Computing log(x) according to log table */ - nx = (two52.x - two52e.x)+add; + { /*Computing log(x) according to log table */ + nx = (two52.x - two52e.x) + add; ou1 = ui.x[i]; - ou2 = ui.x[i+1]; - lu1 = ui.x[i+2]; - lu2 = ui.x[i+3]; - v.x = u.x*(ou1+ou2)+bigv.x; - vv = v.x-bigv.x; - j = v.i[LOW_HALF]&0x0007ffff; - j = j+j+j; - eps = u.x - uu*vv; - ov = vj.x[j]; - lv1 = vj.x[j+1]; - lv2 = vj.x[j+2]; - a = (ou1+ou2)*(1.0+ov); - a1 = (a+1.0e10)-1.0e10; - a2 = a*(1.0-a1*uu*vv); - e1 = eps*a1; - e2 = eps*a2; - e = e1+e2; - e2 = (e1-e)+e2; - t=nx*ln2a.x+lu1+lv1; - t1 = t+e; - t2 = (((t-t1)+e)+(lu2+lv2+nx*ln2b.x+e2))+e*e*(p2+e*(p3+e*p4)); - res=t1+t2; + ou2 = ui.x[i + 1]; + lu1 = ui.x[i + 2]; + lu2 = ui.x[i + 3]; + v.x = u.x * (ou1 + ou2) + bigv.x; + vv = v.x - bigv.x; + j = v.i[LOW_HALF] & 0x0007ffff; + j = j + j + j; + eps = u.x - uu * vv; + ov = vj.x[j]; + lv1 = vj.x[j + 1]; + lv2 = vj.x[j + 2]; + a = (ou1 + ou2) * (1.0 + ov); + a1 = (a + 1.0e10) - 1.0e10; + a2 = a * (1.0 - a1 * uu * vv); + e1 = eps * a1; + e2 = eps * a2; + e = e1 + e2; + e2 = (e1 - e) + e2; + t = nx * ln2a.x + lu1 + lv1; + t1 = t + e; + t2 = ((((t - t1) + e) + (lu2 + lv2 + nx * ln2b.x + e2)) + e * e + * (p2 + e * (p3 + e * p4))); + res = t1 + t2; *error = 1.0e-27; - *delta = (t1-res)+t2; + *delta = (t1 - res) + t2; return res; - } + } } -/**********************************************************************/ -/* Routine receives a double x and checks if it is an integer. If not */ -/* it returns 0, else it returns 1 if even or -1 if odd. */ -/**********************************************************************/ +/* This function receives a double x and checks if it is an integer. If not, + it returns 0, else it returns 1 if even or -1 if odd. */ static int SECTION -checkint(double x) { - union {int4 i[2]; double x;} u; - int k,m,n; +checkint (double x) +{ + union + { + int4 i[2]; + double x; + } u; + int k, m, n; u.x = x; - m = u.i[HIGH_HALF]&0x7fffffff; /* no sign */ - if (m >= 0x7ff00000) return 0; /* x is +/-inf or NaN */ - if (m >= 0x43400000) return 1; /* |x| >= 2**53 */ - if (m < 0x40000000) return 0; /* |x| < 2, can not be 0 or 1 */ + m = u.i[HIGH_HALF] & 0x7fffffff; /* no sign */ + if (m >= 0x7ff00000) + return 0; /* x is +/-inf or NaN */ + if (m >= 0x43400000) + return 1; /* |x| >= 2**53 */ + if (m < 0x40000000) + return 0; /* |x| < 2, can not be 0 or 1 */ n = u.i[LOW_HALF]; - k = (m>>20)-1023; /* 1 <= k <= 52 */ - if (k == 52) return (n&1)? -1:1; /* odd or even*/ - if (k>20) { - if (n<<(k-20)) return 0; /* if not integer */ - return (n<<(k-21))?-1:1; - } - if (n) return 0; /*if not integer*/ - if (k == 20) return (m&1)? -1:1; - if (m<<(k+12)) return 0; - return (m<<(k+11))?-1:1; + k = (m >> 20) - 1023; /* 1 <= k <= 52 */ + if (k == 52) + return (n & 1) ? -1 : 1; /* odd or even */ + if (k > 20) + { + if (n << (k - 20)) + return 0; /* if not integer */ + return (n << (k - 21)) ? -1 : 1; + } + if (n) + return 0; /*if not integer */ + if (k == 20) + return (m & 1) ? -1 : 1; + if (m << (k + 12)) + return 0; + return (m << (k + 11)) ? -1 : 1; } diff --git a/sysdeps/ieee754/dbl-64/e_rem_pio2.c b/sysdeps/ieee754/dbl-64/e_rem_pio2.c index 4478be0b07..2f55ca294b 100644 --- a/sysdeps/ieee754/dbl-64/e_rem_pio2.c +++ b/sysdeps/ieee754/dbl-64/e_rem_pio2.c @@ -57,110 +57,137 @@ static const int32_t npio2_hw[] = { */ static const double -zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ -half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ -two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ -invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ -pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ -pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ -pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ -pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ -pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ -pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ + zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ + two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ + invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ + pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ + pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ + pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ + pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ + pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ + pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ int32_t -__ieee754_rem_pio2(double x, double *y) +__ieee754_rem_pio2 (double x, double *y) { - double z,w,t,r,fn; - double tx[3]; - int32_t e0,i,j,nx,n,ix,hx; - u_int32_t low; + double z, w, t, r, fn; + double tx[3]; + int32_t e0, i, j, nx, n, ix, hx; + u_int32_t low; - GET_HIGH_WORD(hx,x); /* high word of x */ - ix = hx&0x7fffffff; - if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */ - {y[0] = x; y[1] = 0; return 0;} - if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */ - if(hx>0) { - z = x - pio2_1; - if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */ - y[0] = z - pio2_1t; - y[1] = (z-y[0])-pio2_1t; - } else { /* near pi/2, use 33+33+53 bit pi */ - z -= pio2_2; - y[0] = z - pio2_2t; - y[1] = (z-y[0])-pio2_2t; - } - return 1; - } else { /* negative x */ - z = x + pio2_1; - if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */ - y[0] = z + pio2_1t; - y[1] = (z-y[0])+pio2_1t; - } else { /* near pi/2, use 33+33+53 bit pi */ - z += pio2_2; - y[0] = z + pio2_2t; - y[1] = (z-y[0])+pio2_2t; - } - return -1; + GET_HIGH_WORD (hx, x); /* high word of x */ + ix = hx & 0x7fffffff; + if (ix <= 0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */ + { + y[0] = x; y[1] = 0; return 0; + } + if (ix < 0x4002d97c) /* |x| < 3pi/4, special case with n=+-1 */ + { + if (hx > 0) + { + z = x - pio2_1; + if (ix != 0x3ff921fb) /* 33+53 bit pi is good enough */ + { + y[0] = z - pio2_1t; + y[1] = (z - y[0]) - pio2_1t; + } + else /* near pi/2, use 33+33+53 bit pi */ + { + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z - y[0]) - pio2_2t; } + return 1; } - if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */ - t = fabs(x); - n = (int32_t) (t*invpio2+half); - fn = (double)n; - r = t-fn*pio2_1; - w = fn*pio2_1t; /* 1st round good to 85 bit */ - if(n<32&&ix!=npio2_hw[n-1]) { - y[0] = r-w; /* quick check no cancellation */ - } else { - u_int32_t high; - j = ix>>20; - y[0] = r-w; - GET_HIGH_WORD(high,y[0]); - i = j-((high>>20)&0x7ff); - if(i>16) { /* 2nd iteration needed, good to 118 */ - t = r; - w = fn*pio2_2; - r = t-w; - w = fn*pio2_2t-((t-r)-w); - y[0] = r-w; - GET_HIGH_WORD(high,y[0]); - i = j-((high>>20)&0x7ff); - if(i>49) { /* 3rd iteration need, 151 bits acc */ - t = r; /* will cover all possible cases */ - w = fn*pio2_3; - r = t-w; - w = fn*pio2_3t-((t-r)-w); - y[0] = r-w; - } - } + else /* negative x */ + { + z = x + pio2_1; + if (ix != 0x3ff921fb) /* 33+53 bit pi is good enough */ + { + y[0] = z + pio2_1t; + y[1] = (z - y[0]) + pio2_1t; + } + else /* near pi/2, use 33+33+53 bit pi */ + { + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z - y[0]) + pio2_2t; } - y[1] = (r-y[0])-w; - if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} - else return n; + return -1; } - /* - * all other (large) arguments - */ - if(ix>=0x7ff00000) { /* x is inf or NaN */ - y[0]=y[1]=x-x; return 0; + } + if (ix <= 0x413921fb) /* |x| ~<= 2^19*(pi/2), medium size */ + { + t = fabs (x); + n = (int32_t) (t * invpio2 + half); + fn = (double) n; + r = t - fn * pio2_1; + w = fn * pio2_1t; /* 1st round good to 85 bit */ + if (n < 32 && ix != npio2_hw[n - 1]) + { + y[0] = r - w; /* quick check no cancellation */ } - /* set z = scalbn(|x|,ilogb(x)-23) */ - GET_LOW_WORD(low,x); - SET_LOW_WORD(z,low); - e0 = (ix>>20)-1046; /* e0 = ilogb(z)-23; */ - SET_HIGH_WORD(z, ix - ((int32_t)(e0<<20))); - for(i=0;i<2;i++) { - tx[i] = (double)((int32_t)(z)); - z = (z-tx[i])*two24; + else + { + u_int32_t high; + j = ix >> 20; + y[0] = r - w; + GET_HIGH_WORD (high, y[0]); + i = j - ((high >> 20) & 0x7ff); + if (i > 16) /* 2nd iteration needed, good to 118 */ + { + t = r; + w = fn * pio2_2; + r = t - w; + w = fn * pio2_2t - ((t - r) - w); + y[0] = r - w; + GET_HIGH_WORD (high, y[0]); + i = j - ((high >> 20) & 0x7ff); + if (i > 49) /* 3rd iteration need, 151 bits acc */ + { + t = r; /* will cover all possible cases */ + w = fn * pio2_3; + r = t - w; + w = fn * pio2_3t - ((t - r) - w); + y[0] = r - w; + } + } } - tx[2] = z; - nx = 3; - while(tx[nx-1]==zero) nx--; /* skip zero term */ - n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi); - if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + y[1] = (r - y[0]) - w; + if (hx < 0) + { + y[0] = -y[0]; y[1] = -y[1]; return -n; + } + else return n; + } + /* + * all other (large) arguments + */ + if (ix >= 0x7ff00000) /* x is inf or NaN */ + { + y[0] = y[1] = x - x; return 0; + } + /* set z = scalbn(|x|,ilogb(x)-23) */ + GET_LOW_WORD (low, x); + SET_LOW_WORD (z, low); + e0 = (ix >> 20) - 1046; /* e0 = ilogb(z)-23; */ + SET_HIGH_WORD (z, ix - ((int32_t) (e0 << 20))); + for (i = 0; i < 2; i++) + { + tx[i] = (double) ((int32_t) (z)); + z = (z - tx[i]) * two24; + } + tx[2] = z; + nx = 3; + while (tx[nx - 1] == zero) + nx--; /* skip zero term */ + n = __kernel_rem_pio2 (tx, y, e0, nx, 2, two_over_pi); + if (hx < 0) + { + y[0] = -y[0]; y[1] = -y[1]; return -n; + } + return n; } - #endif diff --git a/sysdeps/ieee754/dbl-64/e_remainder.c b/sysdeps/ieee754/dbl-64/e_remainder.c index 2d20bb1dfe..c6a1901b10 100644 --- a/sysdeps/ieee754/dbl-64/e_remainder.c +++ b/sysdeps/ieee754/dbl-64/e_remainder.c @@ -39,89 +39,111 @@ /* An ultimate remainder routine. Given two IEEE double machine numbers x */ /* ,y it computes the correctly rounded (to nearest) value of remainder */ /**************************************************************************/ -double __ieee754_remainder(double x, double y) +double +__ieee754_remainder (double x, double y) { - double z,d,xx; - int4 kx,ky,n,nn,n1,m1,l; - mynumber u,t,w={{0,0}},v={{0,0}},ww={{0,0}},r; - u.x=x; - t.x=y; - kx=u.i[HIGH_HALF]&0x7fffffff; /* no sign for x*/ - t.i[HIGH_HALF]&=0x7fffffff; /*no sign for y */ - ky=t.i[HIGH_HALF]; + double z, d, xx; + int4 kx, ky, n, nn, n1, m1, l; + mynumber u, t, w = { { 0, 0 } }, v = { { 0, 0 } }, ww = { { 0, 0 } }, r; + u.x = x; + t.x = y; + kx = u.i[HIGH_HALF] & 0x7fffffff; /* no sign for x*/ + t.i[HIGH_HALF] &= 0x7fffffff; /*no sign for y */ + ky = t.i[HIGH_HALF]; /*------ |x| < 2^1023 and 2^-970 < |y| < 2^1024 ------------------*/ - if (kx<0x7fe00000 && ky<0x7ff00000 && ky>=0x03500000) { - SET_RESTORE_ROUND_NOEX (FE_TONEAREST); - if (kx+0x00100000<ky) return x; - if ((kx-0x01500000)<ky) { - z=x/t.x; - v.i[HIGH_HALF]=t.i[HIGH_HALF]; - d=(z+big.x)-big.x; - xx=(x-d*v.x)-d*(t.x-v.x); - if (d-z!=0.5&&d-z!=-0.5) return (xx!=0)?xx:((x>0)?ZERO.x:nZERO.x); - else { - if (ABS(xx)>0.5*t.x) return (z>d)?xx-t.x:xx+t.x; - else return xx; - } - } /* (kx<(ky+0x01500000)) */ - else { - r.x=1.0/t.x; - n=t.i[HIGH_HALF]; - nn=(n&0x7ff00000)+0x01400000; - w.i[HIGH_HALF]=n; - ww.x=t.x-w.x; - l=(kx-nn)&0xfff00000; - n1=ww.i[HIGH_HALF]; - m1=r.i[HIGH_HALF]; - while (l>0) { - r.i[HIGH_HALF]=m1-l; - z=u.x*r.x; - w.i[HIGH_HALF]=n+l; - ww.i[HIGH_HALF]=(n1)?n1+l:n1; - d=(z+big.x)-big.x; - u.x=(u.x-d*w.x)-d*ww.x; - l=(u.i[HIGH_HALF]&0x7ff00000)-nn; - } - r.i[HIGH_HALF]=m1; - w.i[HIGH_HALF]=n; - ww.i[HIGH_HALF]=n1; - z=u.x*r.x; - d=(z+big.x)-big.x; - u.x=(u.x-d*w.x)-d*ww.x; - if (ABS(u.x)<0.5*t.x) return (u.x!=0)?u.x:((x>0)?ZERO.x:nZERO.x); + if (kx < 0x7fe00000 && ky < 0x7ff00000 && ky >= 0x03500000) + { + SET_RESTORE_ROUND_NOEX (FE_TONEAREST); + if (kx + 0x00100000 < ky) + return x; + if ((kx - 0x01500000) < ky) + { + z = x / t.x; + v.i[HIGH_HALF] = t.i[HIGH_HALF]; + d = (z + big.x) - big.x; + xx = (x - d * v.x) - d * (t.x - v.x); + if (d - z != 0.5 && d - z != -0.5) + return (xx != 0) ? xx : ((x > 0) ? ZERO.x : nZERO.x); + else + { + if (ABS (xx) > 0.5 * t.x) + return (z > d) ? xx - t.x : xx + t.x; + else + return xx; + } + } /* (kx<(ky+0x01500000)) */ else - if (ABS(u.x)>0.5*t.x) return (d>z)?u.x+t.x:u.x-t.x; - else - {z=u.x/t.x; d=(z+big.x)-big.x; return ((u.x-d*w.x)-d*ww.x);} - } - - } /* (kx<0x7fe00000&&ky<0x7ff00000&&ky>=0x03500000) */ - else { - if (kx<0x7fe00000&&ky<0x7ff00000&&(ky>0||t.i[LOW_HALF]!=0)) { - y=ABS(y)*t128.x; - z=__ieee754_remainder(x,y)*t128.x; - z=__ieee754_remainder(z,y)*tm128.x; - return z; - } - else { - if ((kx&0x7ff00000)==0x7fe00000&&ky<0x7ff00000&&(ky>0||t.i[LOW_HALF]!=0)) { - y=ABS(y); - z=2.0*__ieee754_remainder(0.5*x,y); - d = ABS(z); - if (d <= ABS(d-y)) return z; - else return (z>0)?z-y:z+y; - } - else { /* if x is too big */ - if (ky==0 && t.i[LOW_HALF] == 0) /* y = 0 */ - return (x * y) / (x * y); - else if (kx >= 0x7ff00000 /* x not finite */ - || (ky>0x7ff00000 /* y is NaN */ - || (ky == 0x7ff00000 && t.i[LOW_HALF] != 0))) - return (x * y) / (x * y); + { + r.x = 1.0 / t.x; + n = t.i[HIGH_HALF]; + nn = (n & 0x7ff00000) + 0x01400000; + w.i[HIGH_HALF] = n; + ww.x = t.x - w.x; + l = (kx - nn) & 0xfff00000; + n1 = ww.i[HIGH_HALF]; + m1 = r.i[HIGH_HALF]; + while (l > 0) + { + r.i[HIGH_HALF] = m1 - l; + z = u.x * r.x; + w.i[HIGH_HALF] = n + l; + ww.i[HIGH_HALF] = (n1) ? n1 + l : n1; + d = (z + big.x) - big.x; + u.x = (u.x - d * w.x) - d * ww.x; + l = (u.i[HIGH_HALF] & 0x7ff00000) - nn; + } + r.i[HIGH_HALF] = m1; + w.i[HIGH_HALF] = n; + ww.i[HIGH_HALF] = n1; + z = u.x * r.x; + d = (z + big.x) - big.x; + u.x = (u.x - d * w.x) - d * ww.x; + if (ABS (u.x) < 0.5 * t.x) + return (u.x != 0) ? u.x : ((x > 0) ? ZERO.x : nZERO.x); + else + if (ABS (u.x) > 0.5 * t.x) + return (d > z) ? u.x + t.x : u.x - t.x; + else + { + z = u.x / t.x; d = (z + big.x) - big.x; + return ((u.x - d * w.x) - d * ww.x); + } + } + } /* (kx<0x7fe00000&&ky<0x7ff00000&&ky>=0x03500000) */ + else + { + if (kx < 0x7fe00000 && ky < 0x7ff00000 && (ky > 0 || t.i[LOW_HALF] != 0)) + { + y = ABS (y) * t128.x; + z = __ieee754_remainder (x, y) * t128.x; + z = __ieee754_remainder (z, y) * tm128.x; + return z; + } else - return x; + { + if ((kx & 0x7ff00000) == 0x7fe00000 && ky < 0x7ff00000 && + (ky > 0 || t.i[LOW_HALF] != 0)) + { + y = ABS (y); + z = 2.0 * __ieee754_remainder (0.5 * x, y); + d = ABS (z); + if (d <= ABS (d - y)) + return z; + else + return (z > 0) ? z - y : z + y; + } + else /* if x is too big */ + { + if (ky == 0 && t.i[LOW_HALF] == 0) /* y = 0 */ + return (x * y) / (x * y); + else if (kx >= 0x7ff00000 /* x not finite */ + || (ky > 0x7ff00000 /* y is NaN */ + || (ky == 0x7ff00000 && t.i[LOW_HALF] != 0))) + return (x * y) / (x * y); + else + return x; + } + } } - } - } } strong_alias (__ieee754_remainder, __remainder_finite) diff --git a/sysdeps/ieee754/dbl-64/e_sinh.c b/sysdeps/ieee754/dbl-64/e_sinh.c index b954100baa..851b510aaa 100644 --- a/sysdeps/ieee754/dbl-64/e_sinh.c +++ b/sysdeps/ieee754/dbl-64/e_sinh.c @@ -38,43 +38,50 @@ static char rcsid[] = "$NetBSD: e_sinh.c,v 1.7 1995/05/10 20:46:13 jtc Exp $"; static const double one = 1.0, shuge = 1.0e307; double -__ieee754_sinh(double x) +__ieee754_sinh (double x) { - double t,w,h; - int32_t ix,jx; - u_int32_t lx; + double t, w, h; + int32_t ix, jx; + u_int32_t lx; - /* High word of |x|. */ - GET_HIGH_WORD(jx,x); - ix = jx&0x7fffffff; + /* High word of |x|. */ + GET_HIGH_WORD (jx, x); + ix = jx & 0x7fffffff; - /* x is INF or NaN */ - if(__builtin_expect(ix>=0x7ff00000, 0)) return x+x; + /* x is INF or NaN */ + if (__builtin_expect (ix >= 0x7ff00000, 0)) + return x + x; - h = 0.5; - if (jx<0) h = -h; - /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */ - if (ix < 0x40360000) { /* |x|<22 */ - if (__builtin_expect(ix<0x3e300000, 0)) /* |x|<2**-28 */ - if(shuge+x>one) - return x;/* sinh(tiny) = tiny with inexact */ - t = __expm1(fabs(x)); - if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one)); - return h*(t+t/(t+one)); - } + h = 0.5; + if (jx < 0) + h = -h; + /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */ + if (ix < 0x40360000) /* |x|<22 */ + { + if (__builtin_expect (ix < 0x3e300000, 0)) /* |x|<2**-28 */ + if (shuge + x > one) + return x; + /* sinh(tiny) = tiny with inexact */ + t = __expm1 (fabs (x)); + if (ix < 0x3ff00000) + return h * (2.0 * t - t * t / (t + one)); + return h * (t + t / (t + one)); + } - /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */ - if (ix < 0x40862e42) return h*__ieee754_exp(fabs(x)); + /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */ + if (ix < 0x40862e42) + return h * __ieee754_exp (fabs (x)); - /* |x| in [log(maxdouble), overflowthresold] */ - GET_LOW_WORD(lx,x); - if (ix<0x408633ce || ((ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d))) { - w = __ieee754_exp(0.5*fabs(x)); - t = h*w; - return t*w; - } + /* |x| in [log(maxdouble), overflowthresold] */ + GET_LOW_WORD (lx, x); + if (ix < 0x408633ce || ((ix == 0x408633ce) && (lx <= (u_int32_t) 0x8fb9f87d))) + { + w = __ieee754_exp (0.5 * fabs (x)); + t = h * w; + return t * w; + } - /* |x| > overflowthresold, sinh(x) overflow */ - return x*shuge; + /* |x| > overflowthresold, sinh(x) overflow */ + return x * shuge; } strong_alias (__ieee754_sinh, __sinh_finite) diff --git a/sysdeps/ieee754/dbl-64/e_sqrt.c b/sysdeps/ieee754/dbl-64/e_sqrt.c index 54610eeeab..88809daa76 100644 --- a/sysdeps/ieee754/dbl-64/e_sqrt.c +++ b/sysdeps/ieee754/dbl-64/e_sqrt.c @@ -44,58 +44,97 @@ /* it computes the correctly rounded (to nearest) value of square */ /* root of x. */ /*********************************************************************/ -double __ieee754_sqrt(double x) { +double +__ieee754_sqrt (double x) +{ #include "uroot.h" static const double rt0 = 9.99999999859990725855365213134618E-01, rt1 = 4.99999999495955425917856814202739E-01, rt2 = 3.75017500867345182581453026130850E-01, rt3 = 3.12523626554518656309172508769531E-01; - static const double big = 134217728.0; - double y,t,del,res,res1,hy,z,zz,p,hx,tx,ty,s; - mynumber a,c={{0,0}}; + static const double big = 134217728.0; + double y, t, del, res, res1, hy, z, zz, p, hx, tx, ty, s; + mynumber a, c = { { 0, 0 } }; int4 k; - a.x=x; - k=a.i[HIGH_HALF]; - a.i[HIGH_HALF]=(k&0x001fffff)|0x3fe00000; - t=inroot[(k&0x001fffff)>>14]; - s=a.x; + a.x = x; + k = a.i[HIGH_HALF]; + a.i[HIGH_HALF] = (k & 0x001fffff) | 0x3fe00000; + t = inroot[(k & 0x001fffff) >> 14]; + s = a.x; /*----------------- 2^-1022 <= | x |< 2^1024 -----------------*/ - if (k>0x000fffff && k<0x7ff00000) { - fenv_t env; - libc_feholdexcept (&env); - double ret; - y=1.0-t*(t*s); - t=t*(rt0+y*(rt1+y*(rt2+y*rt3))); - c.i[HIGH_HALF]=0x20000000+((k&0x7fe00000)>>1); - y=t*s; - hy=(y+big)-big; - del=0.5*t*((s-hy*hy)-(y-hy)*(y+hy)); - res=y+del; - if (res == (res+1.002*((y-res)+del))) ret = res*c.x; - else { - res1=res+1.5*((y-res)+del); - EMULV(res,res1,z,zz,p,hx,tx,hy,ty); /* (z+zz)=res*res1 */ - ret = ((((z-s)+zz)<0)?max(res,res1):min(res,res1))*c.x; + if (k > 0x000fffff && k < 0x7ff00000) + { + int rm = fegetround (); + fenv_t env; + libc_feholdexcept_setround (&env, FE_TONEAREST); + double ret; + y = 1.0 - t * (t * s); + t = t * (rt0 + y * (rt1 + y * (rt2 + y * rt3))); + c.i[HIGH_HALF] = 0x20000000 + ((k & 0x7fe00000) >> 1); + y = t * s; + hy = (y + big) - big; + del = 0.5 * t * ((s - hy * hy) - (y - hy) * (y + hy)); + res = y + del; + if (res == (res + 1.002 * ((y - res) + del))) + ret = res * c.x; + else + { + res1 = res + 1.5 * ((y - res) + del); + EMULV (res, res1, z, zz, p, hx, tx, hy, ty); /* (z+zz)=res*res1 */ + res = ((((z - s) + zz) < 0) ? max (res, res1) : + min (res, res1)); + ret = res * c.x; + } + math_force_eval (ret); + libc_fesetenv (&env); + double dret = x / ret; + if (dret != ret) + { + double force_inexact = 1.0 / 3.0; + math_force_eval (force_inexact); + /* The square root is inexact, ret is the round-to-nearest + value which may need adjusting for other rounding + modes. */ + switch (rm) + { +#ifdef FE_UPWARD + case FE_UPWARD: + if (dret > ret) + ret = (res + 0x1p-1022) * c.x; + break; +#endif + +#ifdef FE_DOWNWARD + case FE_DOWNWARD: +#endif +#ifdef FE_TOWARDZERO + case FE_TOWARDZERO: +#endif +#if defined FE_DOWNWARD || defined FE_TOWARDZERO + if (dret < ret) + ret = (res - 0x1p-1022) * c.x; + break; +#endif + + default: + break; + } + } + /* Otherwise (x / ret == ret), either the square root was exact or + the division was inexact. */ + return ret; + } + else + { + if ((k & 0x7ff00000) == 0x7ff00000) + return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */ + if (x == 0) + return x; /* sqrt(+0)=+0, sqrt(-0)=-0 */ + if (k < 0) + return (x - x) / (x - x); /* sqrt(-ve)=sNaN */ + return tm256.x * __ieee754_sqrt (x * t512.x); } - math_force_eval (ret); - libc_fesetenv (&env); - if (x / ret != ret) - { - double force_inexact = 1.0 / 3.0; - math_force_eval (force_inexact); - } - /* Otherwise (x / ret == ret), either the square root was exact or - the division was inexact. */ - return ret; - } - else { - if ((k & 0x7ff00000) == 0x7ff00000) - return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */ - if (x==0) return x; /* sqrt(+0)=+0, sqrt(-0)=-0 */ - if (k<0) return (x-x)/(x-x); /* sqrt(-ve)=sNaN */ - return tm256.x*__ieee754_sqrt(x*t512.x); - } } strong_alias (__ieee754_sqrt, __sqrt_finite) diff --git a/sysdeps/ieee754/dbl-64/halfulp.c b/sysdeps/ieee754/dbl-64/halfulp.c index 8c5a9312a0..382ad7aada 100644 --- a/sysdeps/ieee754/dbl-64/halfulp.c +++ b/sysdeps/ieee754/dbl-64/halfulp.c @@ -44,86 +44,109 @@ #endif static const int4 tab54[32] = { - 262143, 11585, 1782, 511, 210, 107, 63, 42, - 30, 22, 17, 14, 12, 10, 9, 7, - 7, 6, 5, 5, 5, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3 }; + 262143, 11585, 1782, 511, 210, 107, 63, 42, + 30, 22, 17, 14, 12, 10, 9, 7, + 7, 6, 5, 5, 5, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3 +}; double SECTION -__halfulp(double x, double y) +__halfulp (double x, double y) { mynumber v; - double z,u,uu; + double z, u, uu; #ifndef DLA_FMS - double j1,j2,j3,j4,j5; + double j1, j2, j3, j4, j5; #endif - int4 k,l,m,n; - if (y <= 0) { /*if power is negative or zero */ - v.x = y; - if (v.i[LOW_HALF] != 0) return -10.0; - v.x = x; - if (v.i[LOW_HALF] != 0) return -10.0; - if ((v.i[HIGH_HALF]&0x000fffff) != 0) return -10; /* if x =2 ^ n */ - k = ((v.i[HIGH_HALF]&0x7fffffff)>>20)-1023; /* find this n */ - z = (double) k; - return (z*y == -1075.0)?0: -10.0; - } - /* if y > 0 */ + int4 k, l, m, n; + if (y <= 0) /*if power is negative or zero */ + { + v.x = y; + if (v.i[LOW_HALF] != 0) + return -10.0; + v.x = x; + if (v.i[LOW_HALF] != 0) + return -10.0; + if ((v.i[HIGH_HALF] & 0x000fffff) != 0) + return -10; /* if x =2 ^ n */ + k = ((v.i[HIGH_HALF] & 0x7fffffff) >> 20) - 1023; /* find this n */ + z = (double) k; + return (z * y == -1075.0) ? 0 : -10.0; + } + /* if y > 0 */ v.x = y; - if (v.i[LOW_HALF] != 0) return -10.0; + if (v.i[LOW_HALF] != 0) + return -10.0; - v.x=x; - /* case where x = 2**n for some integer n */ - if (((v.i[HIGH_HALF]&0x000fffff)|v.i[LOW_HALF]) == 0) { - k=(v.i[HIGH_HALF]>>20)-1023; - return (((double) k)*y == -1075.0)?0:-10.0; - } + v.x = x; + /* case where x = 2**n for some integer n */ + if (((v.i[HIGH_HALF] & 0x000fffff) | v.i[LOW_HALF]) == 0) + { + k = (v.i[HIGH_HALF] >> 20) - 1023; + return (((double) k) * y == -1075.0) ? 0 : -10.0; + } v.x = y; k = v.i[HIGH_HALF]; - m = k<<12; + m = k << 12; l = 0; while (m) - {m = m<<1; l++; } - n = (k&0x000fffff)|0x00100000; - n = n>>(20-l); /* n is the odd integer of y */ - k = ((k>>20) -1023)-l; /* y = n*2**k */ - if (k>5) return -10.0; - if (k>0) for (;k>0;k--) n *= 2; - if (n > 34) return -10.0; + { + m = m << 1; l++; + } + n = (k & 0x000fffff) | 0x00100000; + n = n >> (20 - l); /* n is the odd integer of y */ + k = ((k >> 20) - 1023) - l; /* y = n*2**k */ + if (k > 5) + return -10.0; + if (k > 0) + for (; k > 0; k--) + n *= 2; + if (n > 34) + return -10.0; k = -k; - if (k>5) return -10.0; + if (k > 5) + return -10.0; - /* now treat x */ - while (k>0) { - z = __ieee754_sqrt(x); - EMULV(z,z,u,uu,j1,j2,j3,j4,j5); - if (((u-x)+uu) != 0) break; - x = z; - k--; - } - if (k) return -10.0; + /* now treat x */ + while (k > 0) + { + z = __ieee754_sqrt (x); + EMULV (z, z, u, uu, j1, j2, j3, j4, j5); + if (((u - x) + uu) != 0) + break; + x = z; + k--; + } + if (k) + return -10.0; /* it is impossible that n == 2, so the mantissa of x must be short */ v.x = x; - if (v.i[LOW_HALF]) return -10.0; + if (v.i[LOW_HALF]) + return -10.0; k = v.i[HIGH_HALF]; - m = k<<12; + m = k << 12; l = 0; - while (m) {m = m<<1; l++; } - m = (k&0x000fffff)|0x00100000; - m = m>>(20-l); /* m is the odd integer of x */ + while (m) + { + m = m << 1; l++; + } + m = (k & 0x000fffff) | 0x00100000; + m = m >> (20 - l); /* m is the odd integer of x */ - /* now check whether the length of m**n is at most 54 bits */ + /* now check whether the length of m**n is at most 54 bits */ - if (m > tab54[n-3]) return -10.0; + if (m > tab54[n - 3]) + return -10.0; - /* yes, it is - now compute x**n by simple multiplications */ + /* yes, it is - now compute x**n by simple multiplications */ u = x; - for (k=1;k<n;k++) u = u*x; + for (k = 1; k < n; k++) + u = u * x; return u; } diff --git a/sysdeps/ieee754/dbl-64/k_rem_pio2.c b/sysdeps/ieee754/dbl-64/k_rem_pio2.c index ec4b4cf600..047c6c2886 100644 --- a/sysdeps/ieee754/dbl-64/k_rem_pio2.c +++ b/sysdeps/ieee754/dbl-64/k_rem_pio2.c @@ -147,166 +147,215 @@ static const double PIo2[] = { }; static const double -zero = 0.0, -one = 1.0, -two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ -twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */ + zero = 0.0, + one = 1.0, + two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ + twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */ -int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int32_t *ipio2) +int +__kernel_rem_pio2 (double *x, double *y, int e0, int nx, int prec, + const int32_t *ipio2) { - int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; - double z,fw,f[20],fq[20],q[20]; + int32_t jz, jx, jv, jp, jk, carry, n, iq[20], i, j, k, m, q0, ih; + double z, fw, f[20], fq[20], q[20]; - /* initialize jk*/ - jk = init_jk[prec]; - jp = jk; + /* initialize jk*/ + jk = init_jk[prec]; + jp = jk; - /* determine jx,jv,q0, note that 3>q0 */ - jx = nx-1; - jv = (e0-3)/24; if(jv<0) jv=0; - q0 = e0-24*(jv+1); + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx - 1; + jv = (e0 - 3) / 24; if (jv < 0) + jv = 0; + q0 = e0 - 24 * (jv + 1); - /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ - j = jv-jx; m = jx+jk; - for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j]; + /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ + j = jv - jx; m = jx + jk; + for (i = 0; i <= m; i++, j++) + f[i] = (j < 0) ? zero : (double) ipio2[j]; - /* compute q[0],q[1],...q[jk] */ - for (i=0;i<=jk;i++) { - for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw; - } + /* compute q[0],q[1],...q[jk] */ + for (i = 0; i <= jk; i++) + { + for (j = 0, fw = 0.0; j <= jx; j++) + fw += x[j] * f[jx + i - j]; + q[i] = fw; + } - jz = jk; + jz = jk; recompute: - /* distill q[] into iq[] reversingly */ - for(i=0,j=jz,z=q[jz];j>0;i++,j--) { - fw = (double)((int32_t)(twon24* z)); - iq[i] = (int32_t)(z-two24*fw); - z = q[j-1]+fw; - } + /* distill q[] into iq[] reversingly */ + for (i = 0, j = jz, z = q[jz]; j > 0; i++, j--) + { + fw = (double) ((int32_t) (twon24 * z)); + iq[i] = (int32_t) (z - two24 * fw); + z = q[j - 1] + fw; + } - /* compute n */ - z = __scalbn(z,q0); /* actual value of z */ - z -= 8.0*__floor(z*0.125); /* trim off integer >= 8 */ - n = (int32_t) z; - z -= (double)n; - ih = 0; - if(q0>0) { /* need iq[jz-1] to determine n */ - i = (iq[jz-1]>>(24-q0)); n += i; - iq[jz-1] -= i<<(24-q0); - ih = iq[jz-1]>>(23-q0); - } - else if(q0==0) ih = iq[jz-1]>>23; - else if(z>=0.5) ih=2; + /* compute n */ + z = __scalbn (z, q0); /* actual value of z */ + z -= 8.0 * __floor (z * 0.125); /* trim off integer >= 8 */ + n = (int32_t) z; + z -= (double) n; + ih = 0; + if (q0 > 0) /* need iq[jz-1] to determine n */ + { + i = (iq[jz - 1] >> (24 - q0)); n += i; + iq[jz - 1] -= i << (24 - q0); + ih = iq[jz - 1] >> (23 - q0); + } + else if (q0 == 0) + ih = iq[jz - 1] >> 23; + else if (z >= 0.5) + ih = 2; - if(ih>0) { /* q > 0.5 */ - n += 1; carry = 0; - for(i=0;i<jz ;i++) { /* compute 1-q */ - j = iq[i]; - if(carry==0) { - if(j!=0) { - carry = 1; iq[i] = 0x1000000- j; - } - } else iq[i] = 0xffffff - j; - } - if(q0>0) { /* rare case: chance is 1 in 12 */ - switch(q0) { - case 1: - iq[jz-1] &= 0x7fffff; break; - case 2: - iq[jz-1] &= 0x3fffff; break; - } + if (ih > 0) /* q > 0.5 */ + { + n += 1; carry = 0; + for (i = 0; i < jz; i++) /* compute 1-q */ + { + j = iq[i]; + if (carry == 0) + { + if (j != 0) + { + carry = 1; iq[i] = 0x1000000 - j; + } } - if(ih==2) { - z = one - z; - if(carry!=0) z -= __scalbn(one,q0); + else + iq[i] = 0xffffff - j; + } + if (q0 > 0) /* rare case: chance is 1 in 12 */ + { + switch (q0) + { + case 1: + iq[jz - 1] &= 0x7fffff; break; + case 2: + iq[jz - 1] &= 0x3fffff; break; } } + if (ih == 2) + { + z = one - z; + if (carry != 0) + z -= __scalbn (one, q0); + } + } - /* check if recomputation is needed */ - if(z==zero) { - j = 0; - for (i=jz-1;i>=jk;i--) j |= iq[i]; - if(j==0) { /* need recomputation */ - for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */ + /* check if recomputation is needed */ + if (z == zero) + { + j = 0; + for (i = jz - 1; i >= jk; i--) + j |= iq[i]; + if (j == 0) /* need recomputation */ + { + for (k = 1; iq[jk - k] == 0; k++) + ; /* k = no. of terms needed */ - for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */ - f[jx+i] = (double) ipio2[jv+i]; - for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; - q[i] = fw; - } - jz += k; - goto recompute; + for (i = jz + 1; i <= jz + k; i++) /* add q[jz+1] to q[jz+k] */ + { + f[jx + i] = (double) ipio2[jv + i]; + for (j = 0, fw = 0.0; j <= jx; j++) + fw += x[j] * f[jx + i - j]; + q[i] = fw; } + jz += k; + goto recompute; } + } - /* chop off zero terms */ - if(z==0.0) { - jz -= 1; q0 -= 24; - while(iq[jz]==0) { jz--; q0-=24;} - } else { /* break z into 24-bit if necessary */ - z = __scalbn(z,-q0); - if(z>=two24) { - fw = (double)((int32_t)(twon24*z)); - iq[jz] = (int32_t)(z-two24*fw); - jz += 1; q0 += 24; - iq[jz] = (int32_t) fw; - } else iq[jz] = (int32_t) z ; + /* chop off zero terms */ + if (z == 0.0) + { + jz -= 1; q0 -= 24; + while (iq[jz] == 0) + { + jz--; q0 -= 24; } - - /* convert integer "bit" chunk to floating-point value */ - fw = __scalbn(one,q0); - for(i=jz;i>=0;i--) { - q[i] = fw*(double)iq[i]; fw*=twon24; + } + else /* break z into 24-bit if necessary */ + { + z = __scalbn (z, -q0); + if (z >= two24) + { + fw = (double) ((int32_t) (twon24 * z)); + iq[jz] = (int32_t) (z - two24 * fw); + jz += 1; q0 += 24; + iq[jz] = (int32_t) fw; } + else + iq[jz] = (int32_t) z; + } - /* compute PIo2[0,...,jp]*q[jz,...,0] */ - for(i=jz;i>=0;i--) { - for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k]; - fq[jz-i] = fw; - } + /* convert integer "bit" chunk to floating-point value */ + fw = __scalbn (one, q0); + for (i = jz; i >= 0; i--) + { + q[i] = fw * (double) iq[i]; fw *= twon24; + } - /* compress fq[] into y[] */ - switch(prec) { - case 0: - fw = 0.0; - for (i=jz;i>=0;i--) fw += fq[i]; - y[0] = (ih==0)? fw: -fw; - break; - case 1: - case 2:; + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for (i = jz; i >= 0; i--) + { + for (fw = 0.0, k = 0; k <= jp && k <= jz - i; k++) + fw += PIo2[k] * q[i + k]; + fq[jz - i] = fw; + } + + /* compress fq[] into y[] */ + switch (prec) + { + case 0: + fw = 0.0; + for (i = jz; i >= 0; i--) + fw += fq[i]; + y[0] = (ih == 0) ? fw : -fw; + break; + case 1: + case 2:; #if __FLT_EVAL_METHOD__ != 0 - volatile + volatile #endif - double fv = 0.0; - for (i=jz;i>=0;i--) fv += fq[i]; - y[0] = (ih==0)? fv: -fv; - fv = fq[0]-fv; - for (i=1;i<=jz;i++) fv += fq[i]; - y[1] = (ih==0)? fv: -fv; - break; - case 3: /* painful */ - for (i=jz;i>0;i--) { + double fv = 0.0; + for (i = jz; i >= 0; i--) + fv += fq[i]; + y[0] = (ih == 0) ? fv : -fv; + fv = fq[0] - fv; + for (i = 1; i <= jz; i++) + fv += fq[i]; + y[1] = (ih == 0) ? fv : -fv; + break; + case 3: /* painful */ + for (i = jz; i > 0; i--) + { #if __FLT_EVAL_METHOD__ != 0 - volatile + volatile #endif - double fv = (double)(fq[i-1]+fq[i]); - fq[i] += fq[i-1]-fv; - fq[i-1] = fv; - } - for (i=jz;i>1;i--) { + double fv = (double) (fq[i - 1] + fq[i]); + fq[i] += fq[i - 1] - fv; + fq[i - 1] = fv; + } + for (i = jz; i > 1; i--) + { #if __FLT_EVAL_METHOD__ != 0 - volatile + volatile #endif - double fv = (double)(fq[i-1]+fq[i]); - fq[i] += fq[i-1]-fv; - fq[i-1] = fv; - } - for (fw=0.0,i=jz;i>=2;i--) fw += fq[i]; - if(ih==0) { - y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; - } else { - y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; - } + double fv = (double) (fq[i - 1] + fq[i]); + fq[i] += fq[i - 1] - fv; + fq[i - 1] = fv; + } + for (fw = 0.0, i = jz; i >= 2; i--) + fw += fq[i]; + if (ih == 0) + { + y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; + } + else + { + y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; } - return n&7; + } + return n & 7; } diff --git a/sysdeps/ieee754/dbl-64/mpa-arch.h b/sysdeps/ieee754/dbl-64/mpa-arch.h index 7de9d51ae2..779a43d9b0 100644 --- a/sysdeps/ieee754/dbl-64/mpa-arch.h +++ b/sysdeps/ieee754/dbl-64/mpa-arch.h @@ -22,15 +22,15 @@ typedef int64_t mantissa_store_t; #define TWOPOW(i) (1L << i) #define RADIX_EXP 24 -#define RADIX TWOPOW (RADIX_EXP) /* 2^24 */ +#define RADIX TWOPOW (RADIX_EXP) /* 2^24 */ /* Divide D by RADIX and put the remainder in R. D must be a non-negative integral value. */ #define DIV_RADIX(d, r) \ - ({ \ - r = d & (RADIX - 1); \ - d >>= RADIX_EXP; \ - }) + ({ \ + r = d & (RADIX - 1); \ + d >>= RADIX_EXP; \ + }) /* Put the integer component of a double X in R and retain the fraction in X. This is used in extracting mantissa digits for MP_NO by using the @@ -38,10 +38,10 @@ typedef int64_t mantissa_store_t; digit and then scaling by RADIX to get the next mantissa digit in the same manner. */ #define INTEGER_OF(x, i) \ - ({ \ - i = (mantissa_t) x; \ - x -= i; \ - }) + ({ \ + i = (mantissa_t) x; \ + x -= i; \ + }) /* Align IN down to F. The code assumes that F is a power of two. */ -#define ALIGN_DOWN_TO(in, f) ((in) & -(f)) +#define ALIGN_DOWN_TO(in, f) ((in) & - (f)) diff --git a/sysdeps/ieee754/dbl-64/mpa.c b/sysdeps/ieee754/dbl-64/mpa.c index a3feb175ed..190e8a6373 100644 --- a/sysdeps/ieee754/dbl-64/mpa.c +++ b/sysdeps/ieee754/dbl-64/mpa.c @@ -50,8 +50,8 @@ #endif #ifndef NO__CONST -const mp_no mpone = {1, {1.0, 1.0}}; -const mp_no mptwo = {1, {1.0, 2.0}}; +const mp_no mpone = { 1, { 1.0, 1.0 } }; +const mp_no mptwo = { 1, { 1.0, 2.0 } }; #endif #ifndef NO___ACR @@ -123,7 +123,7 @@ __cpy (const mp_no *x, mp_no *y, int p) static void norm (const mp_no *x, double *y, int p) { -#define R RADIXI +# define R RADIXI long i; double c; mantissa_t a, u, v, z[5]; @@ -140,7 +140,7 @@ norm (const mp_no *x, double *y, int p) } else { - for (a = 1, z[1] = X[1]; z[1] < TWO23;) + for (a = 1, z[1] = X[1]; z[1] < TWO23; ) { a *= 2; z[1] *= 2; @@ -188,7 +188,7 @@ norm (const mp_no *x, double *y, int p) c *= RADIXI; *y = c; -#undef R +# undef R } /* Convert a multiple precision number *X into a double precision @@ -201,7 +201,7 @@ denorm (const mp_no *x, double *y, int p) double c; mantissa_t u, z[5]; -#define R RADIXI +# define R RADIXI if (EX < -44 || (EX == -44 && X[1] < TWO5)) { *y = 0; @@ -298,7 +298,7 @@ denorm (const mp_no *x, double *y, int p) c = X[0] * ((z[1] + R * (z[2] + R * z[3])) - TWO10); *y = c * TWOM1032; -#undef R +# undef R } /* Convert multiple precision number *X into double precision number *Y. The @@ -394,7 +394,7 @@ add_magnitudes (const mp_no *x, const mp_no *y, mp_no *z, int p) zk = 1; } else - { + { Z[k--] = zk; zk = 0; } @@ -409,7 +409,7 @@ add_magnitudes (const mp_no *x, const mp_no *y, mp_no *z, int p) zk = 1; } else - { + { Z[k--] = zk; zk = 0; } @@ -471,7 +471,7 @@ sub_magnitudes (const mp_no *x, const mp_no *y, mp_no *z, int p) zk = -1; } else - { + { Z[k--] = zk; zk = 0; } @@ -487,18 +487,19 @@ sub_magnitudes (const mp_no *x, const mp_no *y, mp_no *z, int p) zk = -1; } else - { + { Z[k--] = zk; zk = 0; } } /* Normalize. */ - for (i = 1; Z[i] == 0; i++); + for (i = 1; Z[i] == 0; i++) + ; EZ = EZ - i + 1; - for (k = 1; i <= p2 + 1;) + for (k = 1; i <= p2 + 1; ) Z[k++] = Z[i++]; - for (; k <= p2;) + for (; k <= p2; ) Z[k++] = 0; } diff --git a/sysdeps/ieee754/dbl-64/mpatan.c b/sysdeps/ieee754/dbl-64/mpatan.c index 807b16a9bc..a6ae611955 100644 --- a/sysdeps/ieee754/dbl-64/mpatan.c +++ b/sysdeps/ieee754/dbl-64/mpatan.c @@ -43,7 +43,6 @@ void SECTION __mpatan (mp_no *x, mp_no *y, int p) { - int i, m, n; double dx; mp_no mptwoim1 = diff --git a/sysdeps/ieee754/dbl-64/mpn2dbl.c b/sysdeps/ieee754/dbl-64/mpn2dbl.c index 8a2f45b9db..0fada79a0c 100644 --- a/sysdeps/ieee754/dbl-64/mpn2dbl.c +++ b/sysdeps/ieee754/dbl-64/mpn2dbl.c @@ -40,7 +40,7 @@ __mpn_construct_double (mp_srcptr frac_ptr, int expt, int negative) u.ieee.mantissa0 = (frac_ptr[0] >> 32) & (((mp_limb_t) 1 << (DBL_MANT_DIG - 32)) - 1); #else - #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" + # error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" #endif return u.d; diff --git a/sysdeps/ieee754/dbl-64/mptan.c b/sysdeps/ieee754/dbl-64/mptan.c index 281bfca1c3..a5c3fb36c9 100644 --- a/sysdeps/ieee754/dbl-64/mptan.c +++ b/sysdeps/ieee754/dbl-64/mptan.c @@ -44,7 +44,6 @@ void SECTION __mptan (double x, mp_no *mpy, int p) { - int n; mp_no mpw, mpc, mps; diff --git a/sysdeps/ieee754/dbl-64/mydefs.h b/sysdeps/ieee754/dbl-64/mydefs.h index 89ca965c6a..a430397c67 100644 --- a/sysdeps/ieee754/dbl-64/mydefs.h +++ b/sysdeps/ieee754/dbl-64/mydefs.h @@ -28,10 +28,9 @@ #define MY_H typedef int int4; -typedef union {int4 i[2]; double x;} mynumber; - -#define ABS(x) (((x)>0)?(x):-(x)) -#define max(x,y) (((y)>(x))?(y):(x)) -#define min(x,y) (((y)<(x))?(y):(x)) +typedef union { int4 i[2]; double x; } mynumber; +#define ABS(x) (((x) > 0) ? (x) : -(x)) +#define max(x, y) (((y) > (x)) ? (y) : (x)) +#define min(x, y) (((y) < (x)) ? (y) : (x)) #endif diff --git a/sysdeps/ieee754/dbl-64/s_asinh.c b/sysdeps/ieee754/dbl-64/s_asinh.c index 68e854f5f4..5500746848 100644 --- a/sysdeps/ieee754/dbl-64/s_asinh.c +++ b/sysdeps/ieee754/dbl-64/s_asinh.c @@ -25,33 +25,43 @@ #include <math_private.h> static const double -one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ -ln2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ -huge= 1.00000000000000000000e+300; + one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ + ln2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ + huge = 1.00000000000000000000e+300; double -__asinh(double x) +__asinh (double x) { - double w; - int32_t hx,ix; - GET_HIGH_WORD(hx,x); - ix = hx&0x7fffffff; - if(__builtin_expect(ix< 0x3e300000, 0)) { /* |x|<2**-28 */ - if(huge+x>one) return x; /* return x inexact except 0 */ + double w; + int32_t hx, ix; + GET_HIGH_WORD (hx, x); + ix = hx & 0x7fffffff; + if (__builtin_expect (ix < 0x3e300000, 0)) /* |x|<2**-28 */ + { + if (huge + x > one) + return x; /* return x inexact except 0 */ + } + if (__builtin_expect (ix > 0x41b00000, 0)) /* |x| > 2**28 */ + { + if (ix >= 0x7ff00000) + return x + x; /* x is inf or NaN */ + w = __ieee754_log (fabs (x)) + ln2; + } + else + { + double xa = fabs (x); + if (ix > 0x40000000) /* 2**28 > |x| > 2.0 */ + { + w = __ieee754_log (2.0 * xa + one / (__ieee754_sqrt (xa * xa + one) + + xa)); } - if(__builtin_expect(ix>0x41b00000, 0)) { /* |x| > 2**28 */ - if(ix>=0x7ff00000) return x+x; /* x is inf or NaN */ - w = __ieee754_log(fabs(x))+ln2; - } else { - double xa = fabs(x); - if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */ - w = __ieee754_log(2.0*xa+one/(__ieee754_sqrt(xa*xa+one)+xa)); - } else { /* 2.0 > |x| > 2**-28 */ - double t = xa*xa; - w =__log1p(xa+t/(one+__ieee754_sqrt(one+t))); - } + else /* 2.0 > |x| > 2**-28 */ + { + double t = xa * xa; + w = __log1p (xa + t / (one + __ieee754_sqrt (one + t))); } - return __copysign(w, x); + } + return __copysign (w, x); } weak_alias (__asinh, asinh) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/ieee754/dbl-64/s_atan.c b/sysdeps/ieee754/dbl-64/s_atan.c index 7b6c83ffb6..744e961469 100644 --- a/sysdeps/ieee754/dbl-64/s_atan.c +++ b/sysdeps/ieee754/dbl-64/s_atan.c @@ -42,6 +42,7 @@ #include "uatan.tbl" #include "atnat.h" #include <math.h> +#include <stap-probe.h> void __mpatan (mp_no *, mp_no *, int); /* see definition in mpatan.c */ static double atanMp (double, const int[]); @@ -60,7 +61,7 @@ double atan (double x) { double cor, s1, ss1, s2, ss2, t1, t2, t3, t7, t8, t9, t10, u, u2, u3, - v, vv, w, ww, y, yy, z, zz; + v, vv, w, ww, y, yy, z, zz; #ifndef DLA_FMS double t4, t5, t6; #endif @@ -190,17 +191,17 @@ atan (double x) yy = cij[i][4].d + z * yy; yy = cij[i][3].d + z * yy; yy = cij[i][2].d + z * yy; - yy = HPI1 - z * yy; + yy = HPI1 - z * yy; t1 = HPI - cij[i][1].d; if (i < 112) - u3 = U31; /* w < 1/2 */ + u3 = U31; /* w < 1/2 */ else - u3 = U32; /* w >= 1/2 */ + u3 = U32; /* w >= 1/2 */ if ((y = t1 + (yy - u3)) == t1 + (yy + u3)) return __signArctan (x, y); - DIV2 (1 , 0, u, 0, w, ww, t1, t2, t3, t4, t5, t6, t7, t8, t9, + DIV2 (1, 0, u, 0, w, ww, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); t1 = w - hij[i][0].d; EADD (t1, ww, z, zz); @@ -229,7 +230,7 @@ atan (double x) else { if (u < E) - { /* D <= u < E */ + { /* D <= u < E */ w = 1 / u; v = w * w; EMULV (w, u, t1, t2, t3, t4, t5, t6, t7); @@ -247,7 +248,7 @@ atan (double x) if ((y = t3 + (yy - U4)) == t3 + (yy + U4)) return __signArctan (x, y); - DIV2 (1 , 0, u, 0, w, ww, t1, t2, t3, t4, t5, t6, t7, t8, + DIV2 (1, 0, u, 0, w, ww, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); MUL2 (w, ww, w, ww, v, vv, t1, t2, t3, t4, t5, t6, t7, t8); @@ -306,8 +307,12 @@ atanMp (double x, const int pr[]) __mp_dbl (&mpy1, &y1, p); __mp_dbl (&mpy2, &y2, p); if (y1 == y2) - return y1; + { + LIBC_PROBE (slowatan, 3, &p, &x, &y1); + return y1; + } } + LIBC_PROBE (slowatan_inexact, 3, &p, &x, &y1); return y1; /*if impossible to do exact computing */ } diff --git a/sysdeps/ieee754/dbl-64/s_cbrt.c b/sysdeps/ieee754/dbl-64/s_cbrt.c index a7120e1e1f..208a369a6c 100644 --- a/sysdeps/ieee754/dbl-64/s_cbrt.c +++ b/sysdeps/ieee754/dbl-64/s_cbrt.c @@ -51,16 +51,17 @@ __cbrt (double x) if (xe == 0 && fpclassify (x) <= FP_ZERO) return x + x; - u = (0.354895765043919860 - + ((1.50819193781584896 - + ((-2.11499494167371287 - + ((2.44693122563534430 - + ((-1.83469277483613086 - + (0.784932344976639262 - 0.145263899385486377 * xm) * xm) + u = (0.354895765043919860 + + ((1.50819193781584896 + + ((-2.11499494167371287 + + ((2.44693122563534430 + + ((-1.83469277483613086 + + (0.784932344976639262 - 0.145263899385486377 * xm) + * xm) + * xm)) * xm)) - * xm)) - * xm)) - * xm)); + * xm)) + * xm)); t2 = u * u * u; diff --git a/sysdeps/ieee754/dbl-64/s_ceil.c b/sysdeps/ieee754/dbl-64/s_ceil.c index e048c81c20..b2154b407d 100644 --- a/sysdeps/ieee754/dbl-64/s_ceil.c +++ b/sysdeps/ieee754/dbl-64/s_ceil.c @@ -25,44 +25,67 @@ static const double huge = 1.0e300; double -__ceil(double x) +__ceil (double x) { - int32_t i0,i1,j0; - u_int32_t i,j; - EXTRACT_WORDS(i0,i1,x); - j0 = ((i0>>20)&0x7ff)-0x3ff; - if(j0<20) { - if(j0<0) { /* raise inexact if x != 0 */ - math_force_eval(huge+x); - /* return 0*sign(x) if |x|<1 */ - if(i0<0) {i0=0x80000000;i1=0;} - else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;} - } else { - i = (0x000fffff)>>j0; - if(((i0&i)|i1)==0) return x; /* x is integral */ - math_force_eval(huge+x); /* raise inexact flag */ - if(i0>0) i0 += (0x00100000)>>j0; - i0 &= (~i); i1=0; + int32_t i0, i1, j0; + u_int32_t i, j; + EXTRACT_WORDS (i0, i1, x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 20) + { + if (j0 < 0) /* raise inexact if x != 0 */ + { + math_force_eval (huge + x); + /* return 0*sign(x) if |x|<1 */ + if (i0 < 0) + { + i0 = 0x80000000; i1 = 0; } - } else if (j0>51) { - if(j0==0x400) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } else { - i = ((u_int32_t)(0xffffffff))>>(j0-20); - if((i1&i)==0) return x; /* x is integral */ - math_force_eval(huge+x); /* raise inexact flag */ - if(i0>0) { - if(j0==20) i0+=1; - else { - j = i1 + (1<<(52-j0)); - if(j<i1) i0+=1; /* got a carry */ - i1 = j; - } + else if ((i0 | i1) != 0) + { + i0 = 0x3ff00000; i1 = 0; } - i1 &= (~i); } - INSERT_WORDS(x,i0,i1); - return x; + else + { + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) + return x; /* x is integral */ + math_force_eval (huge + x); /* raise inexact flag */ + if (i0 > 0) + i0 += (0x00100000) >> j0; + i0 &= (~i); i1 = 0; + } + } + else if (j0 > 51) + { + if (j0 == 0x400) + return x + x; /* inf or NaN */ + else + return x; /* x is integral */ + } + else + { + i = ((u_int32_t) (0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) + return x; /* x is integral */ + math_force_eval (huge + x); /* raise inexact flag */ + if (i0 > 0) + { + if (j0 == 20) + i0 += 1; + else + { + j = i1 + (1 << (52 - j0)); + if (j < i1) + i0 += 1; /* got a carry */ + i1 = j; + } + } + i1 &= (~i); + } + INSERT_WORDS (x, i0, i1); + return x; } #ifndef __ceil weak_alias (__ceil, ceil) diff --git a/sysdeps/ieee754/dbl-64/s_copysign.c b/sysdeps/ieee754/dbl-64/s_copysign.c index a541ceb05d..9caf24e8f2 100644 --- a/sysdeps/ieee754/dbl-64/s_copysign.c +++ b/sysdeps/ieee754/dbl-64/s_copysign.c @@ -23,13 +23,14 @@ static char rcsid[] = "$NetBSD: s_copysign.c,v 1.8 1995/05/10 20:46:57 jtc Exp $ #include <math.h> #include <math_private.h> -double __copysign(double x, double y) +double +__copysign (double x, double y) { - u_int32_t hx,hy; - GET_HIGH_WORD(hx,x); - GET_HIGH_WORD(hy,y); - SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000)); - return x; + u_int32_t hx, hy; + GET_HIGH_WORD (hx, x); + GET_HIGH_WORD (hy, y); + SET_HIGH_WORD (x, (hx & 0x7fffffff) | (hy & 0x80000000)); + return x; } weak_alias (__copysign, copysign) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/ieee754/dbl-64/s_erf.c b/sysdeps/ieee754/dbl-64/s_erf.c index e25e28d9d5..3f37397224 100644 --- a/sysdeps/ieee754/dbl-64/s_erf.c +++ b/sysdeps/ieee754/dbl-64/s_erf.c @@ -112,185 +112,182 @@ static char rcsid[] = "$NetBSD: s_erf.c,v 1.8 1995/05/10 20:47:05 jtc Exp $"; */ +#include <errno.h> +#include <float.h> #include <math.h> #include <math_private.h> static const double -tiny = 1e-300, -half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ -one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ -two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ - /* c = (float)0.84506291151 */ -erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */ + tiny = 1e-300, + half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ + one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ + two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ +/* c = (float)0.84506291151 */ + erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */ /* * Coefficients for approximation to erf on [0,0.84375] */ -efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */ -efx8= 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */ -pp[] = {1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */ - -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */ - -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */ - -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */ - -2.37630166566501626084e-05}, /* 0xBEF8EAD6, 0x120016AC */ -qq[] = {0.0, 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */ - 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */ - 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */ - 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */ - -3.96022827877536812320e-06}, /* 0xBED09C43, 0x42A26120 */ + efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */ + efx8 = 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */ + pp[] = { 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */ + -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */ + -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */ + -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */ + -2.37630166566501626084e-05 }, /* 0xBEF8EAD6, 0x120016AC */ + qq[] = { 0.0, 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */ + 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */ + 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */ + 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */ + -3.96022827877536812320e-06 }, /* 0xBED09C43, 0x42A26120 */ /* * Coefficients for approximation to erf in [0.84375,1.25] */ -pa[] = {-2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */ - 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */ - -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */ - 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */ - -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */ - 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */ - -2.16637559486879084300e-03}, /* 0xBF61BF38, 0x0A96073F */ -qa[] = {0.0, 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */ - 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */ - 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */ - 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */ - 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */ - 1.19844998467991074170e-02}, /* 0x3F888B54, 0x5735151D */ + pa[] = { -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */ + 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */ + -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */ + 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */ + -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */ + 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */ + -2.16637559486879084300e-03 }, /* 0xBF61BF38, 0x0A96073F */ + qa[] = { 0.0, 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */ + 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */ + 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */ + 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */ + 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */ + 1.19844998467991074170e-02 }, /* 0x3F888B54, 0x5735151D */ /* * Coefficients for approximation to erfc in [1.25,1/0.35] */ -ra[] = {-9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */ - -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */ - -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */ - -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */ - -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */ - -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */ - -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */ - -9.81432934416914548592e+00}, /* 0xC023A0EF, 0xC69AC25C */ -sa[] = {0.0,1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */ - 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */ - 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */ - 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */ - 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */ - 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */ - 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */ - -6.04244152148580987438e-02}, /* 0xBFAEEFF2, 0xEE749A62 */ + ra[] = { -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */ + -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */ + -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */ + -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */ + -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */ + -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */ + -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */ + -9.81432934416914548592e+00 }, /* 0xC023A0EF, 0xC69AC25C */ + sa[] = { 0.0, 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */ + 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */ + 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */ + 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */ + 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */ + 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */ + 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */ + -6.04244152148580987438e-02 }, /* 0xBFAEEFF2, 0xEE749A62 */ /* * Coefficients for approximation to erfc in [1/.35,28] */ -rb[] = {-9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */ - -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */ - -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */ - -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */ - -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */ - -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */ - -4.83519191608651397019e+02}, /* 0xC07E384E, 0x9BDC383F */ -sb[] = {0.0,3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */ - 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */ - 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */ - 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */ - 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */ - 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */ - -2.24409524465858183362e+01}; /* 0xC03670E2, 0x42712D62 */ + rb[] = { -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */ + -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */ + -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */ + -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */ + -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */ + -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */ + -4.83519191608651397019e+02 }, /* 0xC07E384E, 0x9BDC383F */ + sb[] = { 0.0, 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */ + 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */ + 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */ + 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */ + 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */ + 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */ + -2.24409524465858183362e+01 }; /* 0xC03670E2, 0x42712D62 */ -double __erf(double x) +double +__erf (double x) { - int32_t hx,ix,i; - double R,S,P,Q,s,y,z,r; - GET_HIGH_WORD(hx,x); - ix = hx&0x7fffffff; - if(ix>=0x7ff00000) { /* erf(nan)=nan */ - i = ((u_int32_t)hx>>31)<<1; - return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */ - } + int32_t hx, ix, i; + double R, S, P, Q, s, y, z, r; + GET_HIGH_WORD (hx, x); + ix = hx & 0x7fffffff; + if (ix >= 0x7ff00000) /* erf(nan)=nan */ + { + i = ((u_int32_t) hx >> 31) << 1; + return (double) (1 - i) + one / x; /* erf(+-inf)=+-1 */ + } - if(ix < 0x3feb0000) { /* |x|<0.84375 */ - double r1,r2,s1,s2,s3,z2,z4; - if(ix < 0x3e300000) { /* |x|<2**-28 */ - if (ix < 0x00800000) - return 0.125*(8.0*x+efx8*x); /*avoid underflow */ - return x + efx*x; - } - z = x*x; -#ifdef DO_NOT_USE_THIS - r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); - s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); -#else - r1 = pp[0]+z*pp[1]; z2=z*z; - r2 = pp[2]+z*pp[3]; z4=z2*z2; - s1 = one+z*qq[1]; - s2 = qq[2]+z*qq[3]; - s3 = qq[4]+z*qq[5]; - r = r1 + z2*r2 + z4*pp[4]; - s = s1 + z2*s2 + z4*s3; -#endif - y = r/s; - return x + x*y; - } - if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */ - double s2,s4,s6,P1,P2,P3,P4,Q1,Q2,Q3,Q4; - s = fabs(x)-one; -#ifdef DO_NOT_USE_THIS - P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); - Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); -#else - P1 = pa[0]+s*pa[1]; s2=s*s; - Q1 = one+s*qa[1]; s4=s2*s2; - P2 = pa[2]+s*pa[3]; s6=s4*s2; - Q2 = qa[2]+s*qa[3]; - P3 = pa[4]+s*pa[5]; - Q3 = qa[4]+s*qa[5]; - P4 = pa[6]; - Q4 = qa[6]; - P = P1 + s2*P2 + s4*P3 + s6*P4; - Q = Q1 + s2*Q2 + s4*Q3 + s6*Q4; -#endif - if(hx>=0) return erx + P/Q; else return -erx - P/Q; - } - if (ix >= 0x40180000) { /* inf>|x|>=6 */ - if(hx>=0) return one-tiny; else return tiny-one; + if (ix < 0x3feb0000) /* |x|<0.84375 */ + { + double r1, r2, s1, s2, s3, z2, z4; + if (ix < 0x3e300000) /* |x|<2**-28 */ + { + if (ix < 0x00800000) + return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */ + return x + efx * x; } - x = fabs(x); - s = one/(x*x); - if(ix< 0x4006DB6E) { /* |x| < 1/0.35 */ -#ifdef DO_NOT_USE_THIS - R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( - ra5+s*(ra6+s*ra7)))))); - S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( - sa5+s*(sa6+s*(sa7+s*sa8))))))); -#else - double R1,R2,R3,R4,S1,S2,S3,S4,s2,s4,s6,s8; - R1 = ra[0]+s*ra[1];s2 = s*s; - S1 = one+s*sa[1]; s4 = s2*s2; - R2 = ra[2]+s*ra[3];s6 = s4*s2; - S2 = sa[2]+s*sa[3];s8 = s4*s4; - R3 = ra[4]+s*ra[5]; - S3 = sa[4]+s*sa[5]; - R4 = ra[6]+s*ra[7]; - S4 = sa[6]+s*sa[7]; - R = R1 + s2*R2 + s4*R3 + s6*R4; - S = S1 + s2*S2 + s4*S3 + s6*S4 + s8*sa[8]; -#endif - } else { /* |x| >= 1/0.35 */ -#ifdef DO_NOT_USE_THIS - R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( - rb5+s*rb6))))); - S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( - sb5+s*(sb6+s*sb7)))))); -#else - double R1,R2,R3,S1,S2,S3,S4,s2,s4,s6; - R1 = rb[0]+s*rb[1];s2 = s*s; - S1 = one+s*sb[1]; s4 = s2*s2; - R2 = rb[2]+s*rb[3];s6 = s4*s2; - S2 = sb[2]+s*sb[3]; - R3 = rb[4]+s*rb[5]; - S3 = sb[4]+s*sb[5]; - S4 = sb[6]+s*sb[7]; - R = R1 + s2*R2 + s4*R3 + s6*rb[6]; - S = S1 + s2*S2 + s4*S3 + s6*S4; -#endif - } - z = x; - SET_LOW_WORD(z,0); - r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S); - if(hx>=0) return one-r/x; else return r/x-one; + z = x * x; + r1 = pp[0] + z * pp[1]; z2 = z * z; + r2 = pp[2] + z * pp[3]; z4 = z2 * z2; + s1 = one + z * qq[1]; + s2 = qq[2] + z * qq[3]; + s3 = qq[4] + z * qq[5]; + r = r1 + z2 * r2 + z4 * pp[4]; + s = s1 + z2 * s2 + z4 * s3; + y = r / s; + return x + x * y; + } + if (ix < 0x3ff40000) /* 0.84375 <= |x| < 1.25 */ + { + double s2, s4, s6, P1, P2, P3, P4, Q1, Q2, Q3, Q4; + s = fabs (x) - one; + P1 = pa[0] + s * pa[1]; s2 = s * s; + Q1 = one + s * qa[1]; s4 = s2 * s2; + P2 = pa[2] + s * pa[3]; s6 = s4 * s2; + Q2 = qa[2] + s * qa[3]; + P3 = pa[4] + s * pa[5]; + Q3 = qa[4] + s * qa[5]; + P4 = pa[6]; + Q4 = qa[6]; + P = P1 + s2 * P2 + s4 * P3 + s6 * P4; + Q = Q1 + s2 * Q2 + s4 * Q3 + s6 * Q4; + if (hx >= 0) + return erx + P / Q; + else + return -erx - P / Q; + } + if (ix >= 0x40180000) /* inf>|x|>=6 */ + { + if (hx >= 0) + return one - tiny; + else + return tiny - one; + } + x = fabs (x); + s = one / (x * x); + if (ix < 0x4006DB6E) /* |x| < 1/0.35 */ + { + double R1, R2, R3, R4, S1, S2, S3, S4, s2, s4, s6, s8; + R1 = ra[0] + s * ra[1]; s2 = s * s; + S1 = one + s * sa[1]; s4 = s2 * s2; + R2 = ra[2] + s * ra[3]; s6 = s4 * s2; + S2 = sa[2] + s * sa[3]; s8 = s4 * s4; + R3 = ra[4] + s * ra[5]; + S3 = sa[4] + s * sa[5]; + R4 = ra[6] + s * ra[7]; + S4 = sa[6] + s * sa[7]; + R = R1 + s2 * R2 + s4 * R3 + s6 * R4; + S = S1 + s2 * S2 + s4 * S3 + s6 * S4 + s8 * sa[8]; + } + else /* |x| >= 1/0.35 */ + { + double R1, R2, R3, S1, S2, S3, S4, s2, s4, s6; + R1 = rb[0] + s * rb[1]; s2 = s * s; + S1 = one + s * sb[1]; s4 = s2 * s2; + R2 = rb[2] + s * rb[3]; s6 = s4 * s2; + S2 = sb[2] + s * sb[3]; + R3 = rb[4] + s * rb[5]; + S3 = sb[4] + s * sb[5]; + S4 = sb[6] + s * sb[7]; + R = R1 + s2 * R2 + s4 * R3 + s6 * rb[6]; + S = S1 + s2 * S2 + s4 * S3 + s6 * S4; + } + z = x; + SET_LOW_WORD (z, 0); + r = __ieee754_exp (-z * z - 0.5625) * + __ieee754_exp ((z - x) * (z + x) + R / S); + if (hx >= 0) + return one - r / x; + else + return r / x - one; } weak_alias (__erf, erf) #ifdef NO_LONG_DOUBLE @@ -298,117 +295,126 @@ strong_alias (__erf, __erfl) weak_alias (__erf, erfl) #endif -double __erfc(double x) +double +__erfc (double x) { - int32_t hx,ix; - double R,S,P,Q,s,y,z,r; - GET_HIGH_WORD(hx,x); - ix = hx&0x7fffffff; - if(ix>=0x7ff00000) { /* erfc(nan)=nan */ - /* erfc(+-inf)=0,2 */ - return (double)(((u_int32_t)hx>>31)<<1)+one/x; - } + int32_t hx, ix; + double R, S, P, Q, s, y, z, r; + GET_HIGH_WORD (hx, x); + ix = hx & 0x7fffffff; + if (ix >= 0x7ff00000) /* erfc(nan)=nan */ + { /* erfc(+-inf)=0,2 */ + return (double) (((u_int32_t) hx >> 31) << 1) + one / x; + } - if(ix < 0x3feb0000) { /* |x|<0.84375 */ - double r1,r2,s1,s2,s3,z2,z4; - if(ix < 0x3c700000) /* |x|<2**-56 */ - return one-x; - z = x*x; -#ifdef DO_NOT_USE_THIS - r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); - s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); -#else - r1 = pp[0]+z*pp[1]; z2=z*z; - r2 = pp[2]+z*pp[3]; z4=z2*z2; - s1 = one+z*qq[1]; - s2 = qq[2]+z*qq[3]; - s3 = qq[4]+z*qq[5]; - r = r1 + z2*r2 + z4*pp[4]; - s = s1 + z2*s2 + z4*s3; -#endif - y = r/s; - if(hx < 0x3fd00000) { /* x<1/4 */ - return one-(x+x*y); - } else { - r = x*y; - r += (x-half); - return half - r ; - } + if (ix < 0x3feb0000) /* |x|<0.84375 */ + { + double r1, r2, s1, s2, s3, z2, z4; + if (ix < 0x3c700000) /* |x|<2**-56 */ + return one - x; + z = x * x; + r1 = pp[0] + z * pp[1]; z2 = z * z; + r2 = pp[2] + z * pp[3]; z4 = z2 * z2; + s1 = one + z * qq[1]; + s2 = qq[2] + z * qq[3]; + s3 = qq[4] + z * qq[5]; + r = r1 + z2 * r2 + z4 * pp[4]; + s = s1 + z2 * s2 + z4 * s3; + y = r / s; + if (hx < 0x3fd00000) /* x<1/4 */ + { + return one - (x + x * y); } - if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */ - double s2,s4,s6,P1,P2,P3,P4,Q1,Q2,Q3,Q4; - s = fabs(x)-one; -#ifdef DO_NOT_USE_THIS - P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); - Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); -#else - P1 = pa[0]+s*pa[1]; s2=s*s; - Q1 = one+s*qa[1]; s4=s2*s2; - P2 = pa[2]+s*pa[3]; s6=s4*s2; - Q2 = qa[2]+s*qa[3]; - P3 = pa[4]+s*pa[5]; - Q3 = qa[4]+s*qa[5]; - P4 = pa[6]; - Q4 = qa[6]; - P = P1 + s2*P2 + s4*P3 + s6*P4; - Q = Q1 + s2*Q2 + s4*Q3 + s6*Q4; -#endif - if(hx>=0) { - z = one-erx; return z - P/Q; - } else { - z = erx+P/Q; return one+z; - } + else + { + r = x * y; + r += (x - half); + return half - r; } - if (ix < 0x403c0000) { /* |x|<28 */ - x = fabs(x); - s = one/(x*x); - if(ix< 0x4006DB6D) { /* |x| < 1/.35 ~ 2.857143*/ -#ifdef DO_NOT_USE_THIS - R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( - ra5+s*(ra6+s*ra7)))))); - S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( - sa5+s*(sa6+s*(sa7+s*sa8))))))); -#else - double R1,R2,R3,R4,S1,S2,S3,S4,s2,s4,s6,s8; - R1 = ra[0]+s*ra[1];s2 = s*s; - S1 = one+s*sa[1]; s4 = s2*s2; - R2 = ra[2]+s*ra[3];s6 = s4*s2; - S2 = sa[2]+s*sa[3];s8 = s4*s4; - R3 = ra[4]+s*ra[5]; - S3 = sa[4]+s*sa[5]; - R4 = ra[6]+s*ra[7]; - S4 = sa[6]+s*sa[7]; - R = R1 + s2*R2 + s4*R3 + s6*R4; - S = S1 + s2*S2 + s4*S3 + s6*S4 + s8*sa[8]; -#endif - } else { /* |x| >= 1/.35 ~ 2.857143 */ - double R1,R2,R3,S1,S2,S3,S4,s2,s4,s6; - if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */ -#ifdef DO_NOT_USE_THIS - R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( - rb5+s*rb6))))); - S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( - sb5+s*(sb6+s*sb7)))))); -#else - R1 = rb[0]+s*rb[1];s2 = s*s; - S1 = one+s*sb[1]; s4 = s2*s2; - R2 = rb[2]+s*rb[3];s6 = s4*s2; - S2 = sb[2]+s*sb[3]; - R3 = rb[4]+s*rb[5]; - S3 = sb[4]+s*sb[5]; - S4 = sb[6]+s*sb[7]; - R = R1 + s2*R2 + s4*R3 + s6*rb[6]; - S = S1 + s2*S2 + s4*S3 + s6*S4; + } + if (ix < 0x3ff40000) /* 0.84375 <= |x| < 1.25 */ + { + double s2, s4, s6, P1, P2, P3, P4, Q1, Q2, Q3, Q4; + s = fabs (x) - one; + P1 = pa[0] + s * pa[1]; s2 = s * s; + Q1 = one + s * qa[1]; s4 = s2 * s2; + P2 = pa[2] + s * pa[3]; s6 = s4 * s2; + Q2 = qa[2] + s * qa[3]; + P3 = pa[4] + s * pa[5]; + Q3 = qa[4] + s * qa[5]; + P4 = pa[6]; + Q4 = qa[6]; + P = P1 + s2 * P2 + s4 * P3 + s6 * P4; + Q = Q1 + s2 * Q2 + s4 * Q3 + s6 * Q4; + if (hx >= 0) + { + z = one - erx; return z - P / Q; + } + else + { + z = erx + P / Q; return one + z; + } + } + if (ix < 0x403c0000) /* |x|<28 */ + { + x = fabs (x); + s = one / (x * x); + if (ix < 0x4006DB6D) /* |x| < 1/.35 ~ 2.857143*/ + { + double R1, R2, R3, R4, S1, S2, S3, S4, s2, s4, s6, s8; + R1 = ra[0] + s * ra[1]; s2 = s * s; + S1 = one + s * sa[1]; s4 = s2 * s2; + R2 = ra[2] + s * ra[3]; s6 = s4 * s2; + S2 = sa[2] + s * sa[3]; s8 = s4 * s4; + R3 = ra[4] + s * ra[5]; + S3 = sa[4] + s * sa[5]; + R4 = ra[6] + s * ra[7]; + S4 = sa[6] + s * sa[7]; + R = R1 + s2 * R2 + s4 * R3 + s6 * R4; + S = S1 + s2 * S2 + s4 * S3 + s6 * S4 + s8 * sa[8]; + } + else /* |x| >= 1/.35 ~ 2.857143 */ + { + double R1, R2, R3, S1, S2, S3, S4, s2, s4, s6; + if (hx < 0 && ix >= 0x40180000) + return two - tiny; /* x < -6 */ + R1 = rb[0] + s * rb[1]; s2 = s * s; + S1 = one + s * sb[1]; s4 = s2 * s2; + R2 = rb[2] + s * rb[3]; s6 = s4 * s2; + S2 = sb[2] + s * sb[3]; + R3 = rb[4] + s * rb[5]; + S3 = sb[4] + s * sb[5]; + S4 = sb[6] + s * sb[7]; + R = R1 + s2 * R2 + s4 * R3 + s6 * rb[6]; + S = S1 + s2 * S2 + s4 * S3 + s6 * S4; + } + z = x; + SET_LOW_WORD (z, 0); + r = __ieee754_exp (-z * z - 0.5625) * + __ieee754_exp ((z - x) * (z + x) + R / S); + if (hx > 0) + { +#if FLT_EVAL_METHOD != 0 + volatile #endif - } - z = x; - SET_LOW_WORD(z,0); - r = __ieee754_exp(-z*z-0.5625)* - __ieee754_exp((z-x)*(z+x)+R/S); - if(hx>0) return r/x; else return two-r/x; - } else { - if(hx>0) return tiny*tiny; else return two-tiny; + double ret = r / x; + if (ret == 0) + __set_errno (ERANGE); + return ret; + } + else + return two - r / x; + } + else + { + if (hx > 0) + { + __set_errno (ERANGE); + return tiny * tiny; } + else + return two - tiny; + } } weak_alias (__erfc, erfc) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/ieee754/dbl-64/s_expm1.c b/sysdeps/ieee754/dbl-64/s_expm1.c index 1a4bcd979a..9c9bb34559 100644 --- a/sysdeps/ieee754/dbl-64/s_expm1.c +++ b/sysdeps/ieee754/dbl-64/s_expm1.c @@ -11,7 +11,7 @@ */ /* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25, for performance improvement on pipelined processors. -*/ + */ /* expm1(x) * Returns exp(x)-1, the exponential of x minus 1. @@ -113,120 +113,145 @@ #include <math_private.h> #define one Q[0] static const double -huge = 1.0e+300, -tiny = 1.0e-300, -o_threshold = 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */ -ln2_hi = 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */ -ln2_lo = 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */ -invln2 = 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */ - /* scaled coefficients related to expm1 */ -Q[] = {1.0, -3.33333333333331316428e-02, /* BFA11111 111110F4 */ - 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */ - -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */ - 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */ - -2.01099218183624371326e-07}; /* BE8AFDB7 6E09C32D */ + huge = 1.0e+300, + tiny = 1.0e-300, + o_threshold = 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ + ln2_hi = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ + ln2_lo = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ + invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ +/* scaled coefficients related to expm1 */ + Q[] = { 1.0, -3.33333333333331316428e-02, /* BFA11111 111110F4 */ + 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */ + -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */ + 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */ + -2.01099218183624371326e-07 }; /* BE8AFDB7 6E09C32D */ double -__expm1(double x) +__expm1 (double x) { - double y,hi,lo,c,t,e,hxs,hfx,r1,h2,h4,R1,R2,R3; - int32_t k,xsb; - u_int32_t hx; + double y, hi, lo, c, t, e, hxs, hfx, r1, h2, h4, R1, R2, R3; + int32_t k, xsb; + u_int32_t hx; - GET_HIGH_WORD(hx,x); - xsb = hx&0x80000000; /* sign bit of x */ - if(xsb==0) y=x; else y= -x; /* y = |x| */ - hx &= 0x7fffffff; /* high word of |x| */ + GET_HIGH_WORD (hx, x); + xsb = hx & 0x80000000; /* sign bit of x */ + if (xsb == 0) + y = x; + else + y = -x; /* y = |x| */ + hx &= 0x7fffffff; /* high word of |x| */ - /* filter out huge and non-finite argument */ - if(hx >= 0x4043687A) { /* if |x|>=56*ln2 */ - if(hx >= 0x40862E42) { /* if |x|>=709.78... */ - if(hx>=0x7ff00000) { - u_int32_t low; - GET_LOW_WORD(low,x); - if(((hx&0xfffff)|low)!=0) - return x+x; /* NaN */ - else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */ - } - if(x > o_threshold) { - __set_errno (ERANGE); - return huge*huge; /* overflow */ - } + /* filter out huge and non-finite argument */ + if (hx >= 0x4043687A) /* if |x|>=56*ln2 */ + { + if (hx >= 0x40862E42) /* if |x|>=709.78... */ + { + if (hx >= 0x7ff00000) + { + u_int32_t low; + GET_LOW_WORD (low, x); + if (((hx & 0xfffff) | low) != 0) + return x + x; /* NaN */ + else + return (xsb == 0) ? x : -1.0; /* exp(+-inf)={inf,-1} */ } - if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */ - math_force_eval(x+tiny); /* raise inexact */ - return tiny-one; /* return -1 */ + if (x > o_threshold) + { + __set_errno (ERANGE); + return huge * huge; /* overflow */ } } + if (xsb != 0) /* x < -56*ln2, return -1.0 with inexact */ + { + math_force_eval (x + tiny); /* raise inexact */ + return tiny - one; /* return -1 */ + } + } - /* argument reduction */ - if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ - if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ - if(xsb==0) - {hi = x - ln2_hi; lo = ln2_lo; k = 1;} - else - {hi = x + ln2_hi; lo = -ln2_lo; k = -1;} - } else { - k = invln2*x+((xsb==0)?0.5:-0.5); - t = k; - hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ - lo = t*ln2_lo; + /* argument reduction */ + if (hx > 0x3fd62e42) /* if |x| > 0.5 ln2 */ + { + if (hx < 0x3FF0A2B2) /* and |x| < 1.5 ln2 */ + { + if (xsb == 0) + { + hi = x - ln2_hi; lo = ln2_lo; k = 1; + } + else + { + hi = x + ln2_hi; lo = -ln2_lo; k = -1; } - x = hi - lo; - c = (hi-x)-lo; } - else if(hx < 0x3c900000) { /* when |x|<2**-54, return x */ - t = huge+x; /* return x with inexact flags when x!=0 */ - return x - (t-(huge+x)); + else + { + k = invln2 * x + ((xsb == 0) ? 0.5 : -0.5); + t = k; + hi = x - t * ln2_hi; /* t*ln2_hi is exact here */ + lo = t * ln2_lo; } - else k = 0; + x = hi - lo; + c = (hi - x) - lo; + } + else if (hx < 0x3c900000) /* when |x|<2**-54, return x */ + { + t = huge + x; /* return x with inexact flags when x!=0 */ + return x - (t - (huge + x)); + } + else + k = 0; - /* x is now in primary range */ - hfx = 0.5*x; - hxs = x*hfx; -#ifdef DO_NOT_USE_THIS - r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5)))); -#else - R1 = one+hxs*Q[1]; h2 = hxs*hxs; - R2 = Q[2]+hxs*Q[3]; h4 = h2*h2; - R3 = Q[4]+hxs*Q[5]; - r1 = R1 + h2*R2 + h4*R3; -#endif - t = 3.0-r1*hfx; - e = hxs*((r1-t)/(6.0 - x*t)); - if(k==0) return x - (x*e-hxs); /* c is 0 */ - else { - e = (x*(e-c)-c); - e -= hxs; - if(k== -1) return 0.5*(x-e)-0.5; - if(k==1) { - if(x < -0.25) return -2.0*(e-(x+0.5)); - else return one+2.0*(x-e); - } - if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */ - u_int32_t high; - y = one-(e-x); - GET_HIGH_WORD(high,y); - SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */ - return y-one; - } - t = one; - if(k<20) { - u_int32_t high; - SET_HIGH_WORD(t,0x3ff00000 - (0x200000>>k)); /* t=1-2^-k */ - y = t-(e-x); - GET_HIGH_WORD(high,y); - SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */ - } else { - u_int32_t high; - SET_HIGH_WORD(t,((0x3ff-k)<<20)); /* 2^-k */ - y = x-(e+t); - y += one; - GET_HIGH_WORD(high,y); - SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */ - } + /* x is now in primary range */ + hfx = 0.5 * x; + hxs = x * hfx; + R1 = one + hxs * Q[1]; h2 = hxs * hxs; + R2 = Q[2] + hxs * Q[3]; h4 = h2 * h2; + R3 = Q[4] + hxs * Q[5]; + r1 = R1 + h2 * R2 + h4 * R3; + t = 3.0 - r1 * hfx; + e = hxs * ((r1 - t) / (6.0 - x * t)); + if (k == 0) + return x - (x * e - hxs); /* c is 0 */ + else + { + e = (x * (e - c) - c); + e -= hxs; + if (k == -1) + return 0.5 * (x - e) - 0.5; + if (k == 1) + { + if (x < -0.25) + return -2.0 * (e - (x + 0.5)); + else + return one + 2.0 * (x - e); + } + if (k <= -2 || k > 56) /* suffice to return exp(x)-1 */ + { + u_int32_t high; + y = one - (e - x); + GET_HIGH_WORD (high, y); + SET_HIGH_WORD (y, high + (k << 20)); /* add k to y's exponent */ + return y - one; + } + t = one; + if (k < 20) + { + u_int32_t high; + SET_HIGH_WORD (t, 0x3ff00000 - (0x200000 >> k)); /* t=1-2^-k */ + y = t - (e - x); + GET_HIGH_WORD (high, y); + SET_HIGH_WORD (y, high + (k << 20)); /* add k to y's exponent */ + } + else + { + u_int32_t high; + SET_HIGH_WORD (t, ((0x3ff - k) << 20)); /* 2^-k */ + y = x - (e + t); + y += one; + GET_HIGH_WORD (high, y); + SET_HIGH_WORD (y, high + (k << 20)); /* add k to y's exponent */ } - return y; + } + return y; } weak_alias (__expm1, expm1) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/ieee754/dbl-64/s_fabs.c b/sysdeps/ieee754/dbl-64/s_fabs.c index 86f1d52be6..c82c4210ed 100644 --- a/sysdeps/ieee754/dbl-64/s_fabs.c +++ b/sysdeps/ieee754/dbl-64/s_fabs.c @@ -21,12 +21,13 @@ static char rcsid[] = "$NetBSD: s_fabs.c,v 1.7 1995/05/10 20:47:13 jtc Exp $"; #include <math.h> #include <math_private.h> -double __fabs(double x) +double +__fabs (double x) { - u_int32_t high; - GET_HIGH_WORD(high,x); - SET_HIGH_WORD(x,high&0x7fffffff); - return x; + u_int32_t high; + GET_HIGH_WORD (high, x); + SET_HIGH_WORD (x, high & 0x7fffffff); + return x; } weak_alias (__fabs, fabs) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/ieee754/dbl-64/s_finite.c b/sysdeps/ieee754/dbl-64/s_finite.c index 47dad5df2c..49986bbde9 100644 --- a/sysdeps/ieee754/dbl-64/s_finite.c +++ b/sysdeps/ieee754/dbl-64/s_finite.c @@ -23,11 +23,16 @@ static char rcsid[] = "$NetBSD: s_finite.c,v 1.8 1995/05/10 20:47:17 jtc Exp $"; #include <math_private.h> #undef __finite -int __finite(double x) + +#ifndef FINITE +# define FINITE __finite +#endif + +int FINITE(double x) { - int32_t hx; - GET_HIGH_WORD(hx,x); - return (int)((u_int32_t)((hx&0x7fffffff)-0x7ff00000)>>31); + int32_t hx; + GET_HIGH_WORD (hx, x); + return (int) ((u_int32_t) ((hx & 0x7fffffff) - 0x7ff00000) >> 31); } hidden_def (__finite) weak_alias (__finite, finite) diff --git a/sysdeps/ieee754/dbl-64/s_floor.c b/sysdeps/ieee754/dbl-64/s_floor.c index 5c7297842c..bd6afa72e8 100644 --- a/sysdeps/ieee754/dbl-64/s_floor.c +++ b/sysdeps/ieee754/dbl-64/s_floor.c @@ -24,44 +24,67 @@ static const double huge = 1.0e300; -double __floor(double x) +double +__floor (double x) { - int32_t i0,i1,j0; - u_int32_t i,j; - EXTRACT_WORDS(i0,i1,x); - j0 = ((i0>>20)&0x7ff)-0x3ff; - if(j0<20) { - if(j0<0) { /* raise inexact if x != 0 */ - math_force_eval(huge+x);/* return 0*sign(x) if |x|<1 */ - if(i0>=0) {i0=i1=0;} - else if(((i0&0x7fffffff)|i1)!=0) - { i0=0xbff00000;i1=0;} - } else { - i = (0x000fffff)>>j0; - if(((i0&i)|i1)==0) return x; /* x is integral */ - math_force_eval(huge+x); /* raise inexact flag */ - if(i0<0) i0 += (0x00100000)>>j0; - i0 &= (~i); i1=0; + int32_t i0, i1, j0; + u_int32_t i, j; + EXTRACT_WORDS (i0, i1, x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 20) + { + if (j0 < 0) /* raise inexact if x != 0 */ + { + math_force_eval (huge + x); /* return 0*sign(x) if |x|<1 */ + if (i0 >= 0) + { + i0 = i1 = 0; } - } else if (j0>51) { - if(j0==0x400) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } else { - i = ((u_int32_t)(0xffffffff))>>(j0-20); - if((i1&i)==0) return x; /* x is integral */ - math_force_eval(huge+x); /* raise inexact flag */ - if(i0<0) { - if(j0==20) i0+=1; - else { - j = i1+(1<<(52-j0)); - if(j<i1) i0 +=1 ; /* got a carry */ - i1=j; - } + else if (((i0 & 0x7fffffff) | i1) != 0) + { + i0 = 0xbff00000; i1 = 0; } - i1 &= (~i); } - INSERT_WORDS(x,i0,i1); - return x; + else + { + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) + return x; /* x is integral */ + math_force_eval (huge + x); /* raise inexact flag */ + if (i0 < 0) + i0 += (0x00100000) >> j0; + i0 &= (~i); i1 = 0; + } + } + else if (j0 > 51) + { + if (j0 == 0x400) + return x + x; /* inf or NaN */ + else + return x; /* x is integral */ + } + else + { + i = ((u_int32_t) (0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) + return x; /* x is integral */ + math_force_eval (huge + x); /* raise inexact flag */ + if (i0 < 0) + { + if (j0 == 20) + i0 += 1; + else + { + j = i1 + (1 << (52 - j0)); + if (j < i1) + i0 += 1; /* got a carry */ + i1 = j; + } + } + i1 &= (~i); + } + INSERT_WORDS (x, i0, i1); + return x; } #ifndef __floor weak_alias (__floor, floor) diff --git a/sysdeps/ieee754/dbl-64/s_frexp.c b/sysdeps/ieee754/dbl-64/s_frexp.c index 516f561a17..1b8d8500ba 100644 --- a/sysdeps/ieee754/dbl-64/s_frexp.c +++ b/sysdeps/ieee754/dbl-64/s_frexp.c @@ -28,25 +28,28 @@ static char rcsid[] = "$NetBSD: s_frexp.c,v 1.9 1995/05/10 20:47:24 jtc Exp $"; #include <math_private.h> static const double -two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ + two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ -double __frexp(double x, int *eptr) +double +__frexp (double x, int *eptr) { - int32_t hx, ix, lx; - EXTRACT_WORDS(hx,lx,x); - ix = 0x7fffffff&hx; - *eptr = 0; - if(ix>=0x7ff00000||((ix|lx)==0)) return x; /* 0,inf,nan */ - if (ix<0x00100000) { /* subnormal */ - x *= two54; - GET_HIGH_WORD(hx,x); - ix = hx&0x7fffffff; - *eptr = -54; - } - *eptr += (ix>>20)-1022; - hx = (hx&0x800fffff)|0x3fe00000; - SET_HIGH_WORD(x,hx); - return x; + int32_t hx, ix, lx; + EXTRACT_WORDS (hx, lx, x); + ix = 0x7fffffff & hx; + *eptr = 0; + if (ix >= 0x7ff00000 || ((ix | lx) == 0)) + return x; /* 0,inf,nan */ + if (ix < 0x00100000) /* subnormal */ + { + x *= two54; + GET_HIGH_WORD (hx, x); + ix = hx & 0x7fffffff; + *eptr = -54; + } + *eptr += (ix >> 20) - 1022; + hx = (hx & 0x800fffff) | 0x3fe00000; + SET_HIGH_WORD (x, hx); + return x; } weak_alias (__frexp, frexp) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/ieee754/dbl-64/s_isinf.c b/sysdeps/ieee754/dbl-64/s_isinf.c index 886b346f51..46a7266e7f 100644 --- a/sysdeps/ieee754/dbl-64/s_isinf.c +++ b/sysdeps/ieee754/dbl-64/s_isinf.c @@ -19,11 +19,11 @@ static char rcsid[] = "$NetBSD: s_isinf.c,v 1.3 1995/05/11 23:20:14 jtc Exp $"; int __isinf (double x) { - int32_t hx,lx; - EXTRACT_WORDS(hx,lx,x); - lx |= (hx & 0x7fffffff) ^ 0x7ff00000; - lx |= -lx; - return ~(lx >> 31) & (hx >> 30); + int32_t hx, lx; + EXTRACT_WORDS (hx, lx, x); + lx |= (hx & 0x7fffffff) ^ 0x7ff00000; + lx |= -lx; + return ~(lx >> 31) & (hx >> 30); } hidden_def (__isinf) weak_alias (__isinf, isinf) diff --git a/sysdeps/ieee754/dbl-64/s_isinf_ns.c b/sysdeps/ieee754/dbl-64/s_isinf_ns.c index 0ce50352c7..d8142bcf6e 100644 --- a/sysdeps/ieee754/dbl-64/s_isinf_ns.c +++ b/sysdeps/ieee754/dbl-64/s_isinf_ns.c @@ -14,7 +14,7 @@ int __isinf_ns (double x) { - int32_t hx,lx; - EXTRACT_WORDS(hx,lx,x); - return !(lx | ((hx & 0x7fffffff) ^ 0x7ff00000)); + int32_t hx, lx; + EXTRACT_WORDS (hx, lx, x); + return !(lx | ((hx & 0x7fffffff) ^ 0x7ff00000)); } diff --git a/sysdeps/ieee754/dbl-64/s_isnan.c b/sysdeps/ieee754/dbl-64/s_isnan.c index f8958dcbbf..5d9f31be20 100644 --- a/sysdeps/ieee754/dbl-64/s_isnan.c +++ b/sysdeps/ieee754/dbl-64/s_isnan.c @@ -23,14 +23,15 @@ static char rcsid[] = "$NetBSD: s_isnan.c,v 1.8 1995/05/10 20:47:36 jtc Exp $"; #include <math_private.h> #undef __isnan -int __isnan(double x) +int +__isnan (double x) { - int32_t hx,lx; - EXTRACT_WORDS(hx,lx,x); - hx &= 0x7fffffff; - hx |= (u_int32_t)(lx|(-lx))>>31; - hx = 0x7ff00000 - hx; - return (int)(((u_int32_t)hx)>>31); + int32_t hx, lx; + EXTRACT_WORDS (hx, lx, x); + hx &= 0x7fffffff; + hx |= (u_int32_t) (lx | (-lx)) >> 31; + hx = 0x7ff00000 - hx; + return (int) (((u_int32_t) hx) >> 31); } hidden_def (__isnan) weak_alias (__isnan, isnan) diff --git a/sysdeps/ieee754/dbl-64/s_llround.c b/sysdeps/ieee754/dbl-64/s_llround.c index e8c2232e91..7d50a57dd3 100644 --- a/sysdeps/ieee754/dbl-64/s_llround.c +++ b/sysdeps/ieee754/dbl-64/s_llround.c @@ -66,7 +66,7 @@ __llround (double x) else { /* The number is too large. It is left implementation defined - what happens. */ + what happens. */ return (long long int) x; } diff --git a/sysdeps/ieee754/dbl-64/s_log1p.c b/sysdeps/ieee754/dbl-64/s_log1p.c index e3e6860966..ea1dc6ca76 100644 --- a/sysdeps/ieee754/dbl-64/s_log1p.c +++ b/sysdeps/ieee754/dbl-64/s_log1p.c @@ -11,7 +11,7 @@ */ /* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25, for performance improvement on pipelined processors. -*/ + */ /* double log1p(double x) * @@ -82,91 +82,112 @@ #include <math_private.h> static const double -ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ -ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ -two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ -Lp[] = {0.0, 6.666666666666735130e-01, /* 3FE55555 55555593 */ - 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ - 2.857142874366239149e-01, /* 3FD24924 94229359 */ - 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ - 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ - 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ - 1.479819860511658591e-01}; /* 3FC2F112 DF3E5244 */ + ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ + ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ + two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ + Lp[] = { 0.0, 6.666666666666735130e-01, /* 3FE55555 55555593 */ + 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ + 2.857142874366239149e-01, /* 3FD24924 94229359 */ + 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ + 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ + 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ + 1.479819860511658591e-01 }; /* 3FC2F112 DF3E5244 */ static const double zero = 0.0; double -__log1p(double x) +__log1p (double x) { - double hfsq,f,c,s,z,R,u,z2,z4,z6,R1,R2,R3,R4; - int32_t k,hx,hu,ax; + double hfsq, f, c, s, z, R, u, z2, z4, z6, R1, R2, R3, R4; + int32_t k, hx, hu, ax; - GET_HIGH_WORD(hx,x); - ax = hx&0x7fffffff; + GET_HIGH_WORD (hx, x); + ax = hx & 0x7fffffff; - k = 1; - if (hx < 0x3FDA827A) { /* x < 0.41422 */ - if(__builtin_expect(ax>=0x3ff00000, 0)) { /* x <= -1.0 */ - if(x==-1.0) return -two54/(x-x);/* log1p(-1)=+inf */ - else return (x-x)/(x-x); /* log1p(x<-1)=NaN */ - } - if(__builtin_expect(ax<0x3e200000, 0)) { /* |x| < 2**-29 */ - math_force_eval(two54+x); /* raise inexact */ - if (ax<0x3c900000) /* |x| < 2**-54 */ - return x; - else - return x - x*x*0.5; - } - if(hx>0||hx<=((int32_t)0xbfd2bec3)) { - k=0;f=x;hu=1;} /* -0.2929<x<0.41422 */ + k = 1; + if (hx < 0x3FDA827A) /* x < 0.41422 */ + { + if (__builtin_expect (ax >= 0x3ff00000, 0)) /* x <= -1.0 */ + { + if (x == -1.0) + return -two54 / (x - x); /* log1p(-1)=+inf */ + else + return (x - x) / (x - x); /* log1p(x<-1)=NaN */ } - else if (__builtin_expect(hx >= 0x7ff00000, 0)) return x+x; - if(k!=0) { - if(hx<0x43400000) { - u = 1.0+x; - GET_HIGH_WORD(hu,u); - k = (hu>>20)-1023; - c = (k>0)? 1.0-(u-x):x-(u-1.0);/* correction term */ - c /= u; - } else { - u = x; - GET_HIGH_WORD(hu,u); - k = (hu>>20)-1023; - c = 0; - } - hu &= 0x000fffff; - if(hu<0x6a09e) { - SET_HIGH_WORD(u,hu|0x3ff00000); /* normalize u */ - } else { - k += 1; - SET_HIGH_WORD(u,hu|0x3fe00000); /* normalize u/2 */ - hu = (0x00100000-hu)>>2; - } - f = u-1.0; + if (__builtin_expect (ax < 0x3e200000, 0)) /* |x| < 2**-29 */ + { + math_force_eval (two54 + x); /* raise inexact */ + if (ax < 0x3c900000) /* |x| < 2**-54 */ + return x; + else + return x - x * x * 0.5; } - hfsq=0.5*f*f; - if(hu==0) { /* |f| < 2**-20 */ - if(f==zero) { - if(k==0) return zero; - else {c += k*ln2_lo; return k*ln2_hi+c;} + if (hx > 0 || hx <= ((int32_t) 0xbfd2bec3)) + { + k = 0; f = x; hu = 1; + } /* -0.2929<x<0.41422 */ + } + else if (__builtin_expect (hx >= 0x7ff00000, 0)) + return x + x; + if (k != 0) + { + if (hx < 0x43400000) + { + u = 1.0 + x; + GET_HIGH_WORD (hu, u); + k = (hu >> 20) - 1023; + c = (k > 0) ? 1.0 - (u - x) : x - (u - 1.0); /* correction term */ + c /= u; + } + else + { + u = x; + GET_HIGH_WORD (hu, u); + k = (hu >> 20) - 1023; + c = 0; + } + hu &= 0x000fffff; + if (hu < 0x6a09e) + { + SET_HIGH_WORD (u, hu | 0x3ff00000); /* normalize u */ + } + else + { + k += 1; + SET_HIGH_WORD (u, hu | 0x3fe00000); /* normalize u/2 */ + hu = (0x00100000 - hu) >> 2; + } + f = u - 1.0; + } + hfsq = 0.5 * f * f; + if (hu == 0) /* |f| < 2**-20 */ + { + if (f == zero) + { + if (k == 0) + return zero; + else + { + c += k * ln2_lo; return k * ln2_hi + c; } - R = hfsq*(1.0-0.66666666666666666*f); - if(k==0) return f-R; else - return k*ln2_hi-((R-(k*ln2_lo+c))-f); } - s = f/(2.0+f); - z = s*s; -#ifdef DO_NOT_USE_THIS - R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7)))))); -#else - R1 = z*Lp[1]; z2=z*z; - R2 = Lp[2]+z*Lp[3]; z4=z2*z2; - R3 = Lp[4]+z*Lp[5]; z6=z4*z2; - R4 = Lp[6]+z*Lp[7]; - R = R1 + z2*R2 + z4*R3 + z6*R4; -#endif - if(k==0) return f-(hfsq-s*(hfsq+R)); else - return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f); + R = hfsq * (1.0 - 0.66666666666666666 * f); + if (k == 0) + return f - R; + else + return k * ln2_hi - ((R - (k * ln2_lo + c)) - f); + } + s = f / (2.0 + f); + z = s * s; + R1 = z * Lp[1]; z2 = z * z; + R2 = Lp[2] + z * Lp[3]; z4 = z2 * z2; + R3 = Lp[4] + z * Lp[5]; z6 = z4 * z2; + R4 = Lp[6] + z * Lp[7]; + R = R1 + z2 * R2 + z4 * R3 + z6 * R4; + if (k == 0) + return f - (hfsq - s * (hfsq + R)); + else + return k * ln2_hi - ((hfsq - (s * (hfsq + R) + (k * ln2_lo + c))) - f); } weak_alias (__log1p, log1p) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/ieee754/dbl-64/s_logb.c b/sysdeps/ieee754/dbl-64/s_logb.c index 17aa94b755..c065826dd2 100644 --- a/sysdeps/ieee754/dbl-64/s_logb.c +++ b/sysdeps/ieee754/dbl-64/s_logb.c @@ -25,7 +25,7 @@ __logb (double x) int32_t lx, ix, rix; EXTRACT_WORDS (ix, lx, x); - ix &= 0x7fffffff; /* high |x| */ + ix &= 0x7fffffff; /* high |x| */ if ((ix | lx) == 0) return -1.0 / fabs (x); if (ix >= 0x7ff00000) diff --git a/sysdeps/ieee754/dbl-64/s_lrint.c b/sysdeps/ieee754/dbl-64/s_lrint.c index a68c97e599..1c3037364b 100644 --- a/sysdeps/ieee754/dbl-64/s_lrint.c +++ b/sysdeps/ieee754/dbl-64/s_lrint.c @@ -33,7 +33,7 @@ long int __lrint (double x) { int32_t j0; - u_int32_t i0,i1; + u_int32_t i0, i1; volatile double w; double t; long int result; diff --git a/sysdeps/ieee754/dbl-64/s_modf.c b/sysdeps/ieee754/dbl-64/s_modf.c index b9911c1af6..1dce6381ae 100644 --- a/sysdeps/ieee754/dbl-64/s_modf.c +++ b/sysdeps/ieee754/dbl-64/s_modf.c @@ -25,45 +25,59 @@ static const double one = 1.0; double -__modf(double x, double *iptr) +__modf (double x, double *iptr) { - int32_t i0,i1,j0; - u_int32_t i; - EXTRACT_WORDS(i0,i1,x); - j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ - if(j0<20) { /* integer part in high x */ - if(j0<0) { /* |x|<1 */ - INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ - return x; - } else { - i = (0x000fffff)>>j0; - if(((i0&i)|i1)==0) { /* x is integral */ - *iptr = x; - INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */ - return x; - } else { - INSERT_WORDS(*iptr,i0&(~i),0); - return x - *iptr; - } + int32_t i0, i1, j0; + u_int32_t i; + EXTRACT_WORDS (i0, i1, x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; /* exponent of x */ + if (j0 < 20) /* integer part in high x */ + { + if (j0 < 0) /* |x|<1 */ + { + INSERT_WORDS (*iptr, i0 & 0x80000000, 0); /* *iptr = +-0 */ + return x; + } + else + { + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) /* x is integral */ + { + *iptr = x; + INSERT_WORDS (x, i0 & 0x80000000, 0); /* return +-0 */ + return x; } - } else if (__builtin_expect(j0>51, 0)) { /* no fraction part */ - *iptr = x*one; - /* We must handle NaNs separately. */ - if (j0 == 0x400 && ((i0 & 0xfffff) | i1)) - return x*one; - INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */ - return x; - } else { /* fraction part in low x */ - i = ((u_int32_t)(0xffffffff))>>(j0-20); - if((i1&i)==0) { /* x is integral */ - *iptr = x; - INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */ - return x; - } else { - INSERT_WORDS(*iptr,i0,i1&(~i)); - return x - *iptr; + else + { + INSERT_WORDS (*iptr, i0 & (~i), 0); + return x - *iptr; } } + } + else if (__builtin_expect (j0 > 51, 0)) /* no fraction part */ + { + *iptr = x * one; + /* We must handle NaNs separately. */ + if (j0 == 0x400 && ((i0 & 0xfffff) | i1)) + return x * one; + INSERT_WORDS (x, i0 & 0x80000000, 0); /* return +-0 */ + return x; + } + else /* fraction part in low x */ + { + i = ((u_int32_t) (0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) /* x is integral */ + { + *iptr = x; + INSERT_WORDS (x, i0 & 0x80000000, 0); /* return +-0 */ + return x; + } + else + { + INSERT_WORDS (*iptr, i0, i1 & (~i)); + return x - *iptr; + } + } } weak_alias (__modf, modf) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/ieee754/dbl-64/s_nearbyint.c b/sysdeps/ieee754/dbl-64/s_nearbyint.c index 5017f471d2..dec0c5d6ee 100644 --- a/sysdeps/ieee754/dbl-64/s_nearbyint.c +++ b/sysdeps/ieee754/dbl-64/s_nearbyint.c @@ -29,40 +29,47 @@ static char rcsid[] = "$NetBSD: s_rint.c,v 1.8 1995/05/10 20:48:04 jtc Exp $"; #include <math_private.h> static const double -TWO52[2]={ + TWO52[2] = { 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ }; -double __nearbyint(double x) +double +__nearbyint (double x) { - fenv_t env; - int32_t i0,j0,sx; - double w,t; - GET_HIGH_WORD(i0,x); - sx = (i0>>31)&1; - j0 = ((i0>>20)&0x7ff)-0x3ff; - if(j0<52) { - if(j0<0) { - libc_feholdexcept (&env); - w = TWO52[sx]+x; - t = w-TWO52[sx]; - math_force_eval (t); - libc_fesetenv (&env); - GET_HIGH_WORD(i0,t); - SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31)); - return t; - } - } else { - if(j0==0x400) return x+x; /* inf or NaN */ - else return x; /* x is integral */ + fenv_t env; + int32_t i0, j0, sx; + double w, t; + GET_HIGH_WORD (i0, x); + sx = (i0 >> 31) & 1; + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 52) + { + if (j0 < 0) + { + libc_feholdexcept (&env); + w = TWO52[sx] + x; + t = w - TWO52[sx]; + math_force_eval (t); + libc_fesetenv (&env); + GET_HIGH_WORD (i0, t); + SET_HIGH_WORD (t, (i0 & 0x7fffffff) | (sx << 31)); + return t; } - libc_feholdexcept (&env); - w = TWO52[sx]+x; - t = w-TWO52[sx]; - math_force_eval (t); - libc_fesetenv (&env); - return t; + } + else + { + if (j0 == 0x400) + return x + x; /* inf or NaN */ + else + return x; /* x is integral */ + } + libc_feholdexcept (&env); + w = TWO52[sx] + x; + t = w - TWO52[sx]; + math_force_eval (t); + libc_fesetenv (&env); + return t; } weak_alias (__nearbyint, nearbyint) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/ieee754/dbl-64/s_remquo.c b/sysdeps/ieee754/dbl-64/s_remquo.c index 642581edee..c406150043 100644 --- a/sysdeps/ieee754/dbl-64/s_remquo.c +++ b/sysdeps/ieee754/dbl-64/s_remquo.c @@ -28,8 +28,8 @@ static const double zero = 0.0; double __remquo (double x, double y, int *quo) { - int32_t hx,hy; - u_int32_t sx,lx,ly; + int32_t hx, hy; + u_int32_t sx, lx, ly; int cquo, qs; EXTRACT_WORDS (hx, lx, x); @@ -41,14 +41,14 @@ __remquo (double x, double y, int *quo) /* Purge off exception values. */ if ((hy | ly) == 0) - return (x * y) / (x * y); /* y = 0 */ - if ((hx >= 0x7ff00000) /* x not finite */ - || ((hy >= 0x7ff00000) /* p is NaN */ + return (x * y) / (x * y); /* y = 0 */ + if ((hx >= 0x7ff00000) /* x not finite */ + || ((hy >= 0x7ff00000) /* p is NaN */ && (((hy - 0x7ff00000) | ly) != 0))) return (x * y) / (x * y); if (hy <= 0x7fbfffff) - x = __ieee754_fmod (x, 8 * y); /* now x < 8y */ + x = __ieee754_fmod (x, 8 * y); /* now x < 8y */ if (((hx - hy) | (lx - ly)) == 0) { @@ -56,8 +56,8 @@ __remquo (double x, double y, int *quo) return zero * x; } - x = fabs (x); - y = fabs (y); + x = fabs (x); + y = fabs (y); cquo = 0; if (x >= 4 * y) diff --git a/sysdeps/ieee754/dbl-64/s_rint.c b/sysdeps/ieee754/dbl-64/s_rint.c index 8458909165..a9c0d27842 100644 --- a/sysdeps/ieee754/dbl-64/s_rint.c +++ b/sysdeps/ieee754/dbl-64/s_rint.c @@ -24,33 +24,39 @@ #include <math_private.h> static const double -TWO52[2]={ + TWO52[2] = { 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ }; double -__rint(double x) +__rint (double x) { - int32_t i0,j0,sx; - double w,t; - GET_HIGH_WORD(i0,x); - sx = (i0>>31)&1; - j0 = ((i0>>20)&0x7ff)-0x3ff; - if(j0<52) { - if(j0<0) { - w = TWO52[sx]+x; - t = w-TWO52[sx]; - GET_HIGH_WORD(i0,t); - SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31)); - return t; - } - } else { - if(j0==0x400) return x+x; /* inf or NaN */ - else return x; /* x is integral */ + int32_t i0, j0, sx; + double w, t; + GET_HIGH_WORD (i0, x); + sx = (i0 >> 31) & 1; + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 52) + { + if (j0 < 0) + { + w = TWO52[sx] + x; + t = w - TWO52[sx]; + GET_HIGH_WORD (i0, t); + SET_HIGH_WORD (t, (i0 & 0x7fffffff) | (sx << 31)); + return t; } - w = TWO52[sx]+x; - return w-TWO52[sx]; + } + else + { + if (j0 == 0x400) + return x + x; /* inf or NaN */ + else + return x; /* x is integral */ + } + w = TWO52[sx] + x; + return w - TWO52[sx]; } #ifndef __rint weak_alias (__rint, rint) diff --git a/sysdeps/ieee754/dbl-64/s_scalbln.c b/sysdeps/ieee754/dbl-64/s_scalbln.c index 271a24c3ea..6402927d23 100644 --- a/sysdeps/ieee754/dbl-64/s_scalbln.c +++ b/sysdeps/ieee754/dbl-64/s_scalbln.c @@ -20,38 +20,43 @@ #include <math_private.h> static const double -two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ -twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ -huge = 1.0e+300, -tiny = 1.0e-300; + two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ + twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ + huge = 1.0e+300, + tiny = 1.0e-300; double __scalbln (double x, long int n) { - int32_t k,hx,lx; - EXTRACT_WORDS(hx,lx,x); - k = (hx&0x7ff00000)>>20; /* extract exponent */ - if (__builtin_expect(k==0, 0)) { /* 0 or subnormal x */ - if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ - x *= two54; - GET_HIGH_WORD(hx,x); - k = ((hx&0x7ff00000)>>20) - 54; - } - if (__builtin_expect(k==0x7ff, 0)) return x+x; /* NaN or Inf */ - if (__builtin_expect(n< -50000, 0)) - return tiny*__copysign(tiny,x); /*underflow*/ - if (__builtin_expect(n> 50000 || k+n > 0x7fe, 0)) - return huge*__copysign(huge,x); /* overflow */ - /* Now k and n are bounded we know that k = k+n does not - overflow. */ - k = k+n; - if (__builtin_expect(k > 0, 1)) /* normal result */ - {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;} - if (k <= -54) - return tiny*__copysign(tiny,x); /*underflow*/ - k += 54; /* subnormal result */ - SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); - return x*twom54; + int32_t k, hx, lx; + EXTRACT_WORDS (hx, lx, x); + k = (hx & 0x7ff00000) >> 20; /* extract exponent */ + if (__builtin_expect (k == 0, 0)) /* 0 or subnormal x */ + { + if ((lx | (hx & 0x7fffffff)) == 0) + return x; /* +-0 */ + x *= two54; + GET_HIGH_WORD (hx, x); + k = ((hx & 0x7ff00000) >> 20) - 54; + } + if (__builtin_expect (k == 0x7ff, 0)) + return x + x; /* NaN or Inf */ + if (__builtin_expect (n < -50000, 0)) + return tiny * __copysign (tiny, x); /*underflow*/ + if (__builtin_expect (n > 50000 || k + n > 0x7fe, 0)) + return huge * __copysign (huge, x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k + n; + if (__builtin_expect (k > 0, 1)) /* normal result */ + { + SET_HIGH_WORD (x, (hx & 0x800fffff) | (k << 20)); return x; + } + if (k <= -54) + return tiny * __copysign (tiny, x); /*underflow*/ + k += 54; /* subnormal result */ + SET_HIGH_WORD (x, (hx & 0x800fffff) | (k << 20)); + return x * twom54; } weak_alias (__scalbln, scalbln) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/ieee754/dbl-64/s_scalbn.c b/sysdeps/ieee754/dbl-64/s_scalbn.c index 1f302557ef..6e7d5ad217 100644 --- a/sysdeps/ieee754/dbl-64/s_scalbn.c +++ b/sysdeps/ieee754/dbl-64/s_scalbn.c @@ -20,38 +20,43 @@ #include <math_private.h> static const double -two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ -twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ -huge = 1.0e+300, -tiny = 1.0e-300; + two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ + twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ + huge = 1.0e+300, + tiny = 1.0e-300; double __scalbn (double x, int n) { - int32_t k,hx,lx; - EXTRACT_WORDS(hx,lx,x); - k = (hx&0x7ff00000)>>20; /* extract exponent */ - if (__builtin_expect(k==0, 0)) { /* 0 or subnormal x */ - if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ - x *= two54; - GET_HIGH_WORD(hx,x); - k = ((hx&0x7ff00000)>>20) - 54; - } - if (__builtin_expect(k==0x7ff, 0)) return x+x; /* NaN or Inf */ - if (__builtin_expect(n< -50000, 0)) - return tiny*__copysign(tiny,x); /*underflow*/ - if (__builtin_expect(n> 50000 || k+n > 0x7fe, 0)) - return huge*__copysign(huge,x); /* overflow */ - /* Now k and n are bounded we know that k = k+n does not - overflow. */ - k = k+n; - if (__builtin_expect(k > 0, 1)) /* normal result */ - {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;} - if (k <= -54) - return tiny*__copysign(tiny,x); /*underflow*/ - k += 54; /* subnormal result */ - SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); - return x*twom54; + int32_t k, hx, lx; + EXTRACT_WORDS (hx, lx, x); + k = (hx & 0x7ff00000) >> 20; /* extract exponent */ + if (__builtin_expect (k == 0, 0)) /* 0 or subnormal x */ + { + if ((lx | (hx & 0x7fffffff)) == 0) + return x; /* +-0 */ + x *= two54; + GET_HIGH_WORD (hx, x); + k = ((hx & 0x7ff00000) >> 20) - 54; + } + if (__builtin_expect (k == 0x7ff, 0)) + return x + x; /* NaN or Inf */ + if (__builtin_expect (n < -50000, 0)) + return tiny * __copysign (tiny, x); /*underflow*/ + if (__builtin_expect (n > 50000 || k + n > 0x7fe, 0)) + return huge * __copysign (huge, x); /* overflow */ + /* Now k and n are bounded we know that k = k+n does not + overflow. */ + k = k + n; + if (__builtin_expect (k > 0, 1)) /* normal result */ + { + SET_HIGH_WORD (x, (hx & 0x800fffff) | (k << 20)); return x; + } + if (k <= -54) + return tiny * __copysign (tiny, x); /*underflow*/ + k += 54; /* subnormal result */ + SET_HIGH_WORD (x, (hx & 0x800fffff) | (k << 20)); + return x * twom54; } weak_alias (__scalbn, scalbn) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c index 5c388c8b93..9066667040 100644 --- a/sysdeps/ieee754/dbl-64/s_sin.c +++ b/sysdeps/ieee754/dbl-64/s_sin.c @@ -55,6 +55,58 @@ #include <math_private.h> #include <fenv.h> +/* Helper macros to compute sin of the input values. */ +#define POLYNOMIAL2(xx) ((((s5 * (xx) + s4) * (xx) + s3) * (xx) + s2) * (xx)) + +#define POLYNOMIAL(xx) (POLYNOMIAL2 (xx) + s1) + +/* The computed polynomial is a variation of the Taylor series expansion for + sin(a): + + a - a^3/3! + a^5/5! - a^7/7! + a^9/9! + (1 - a^2) * da / 2 + + The constants s1, s2, s3, etc. are pre-computed values of 1/3!, 1/5! and so + on. The result is returned to LHS and correction in COR. */ +#define TAYLOR_SIN(xx, a, da, cor) \ +({ \ + double t = ((POLYNOMIAL (xx) * (a) - 0.5 * (da)) * (xx) + (da)); \ + double res = (a) + t; \ + (cor) = ((a) - res) + t; \ + res; \ +}) + +/* This is again a variation of the Taylor series expansion with the term + x^3/3! expanded into the following for better accuracy: + + bb * x ^ 3 + 3 * aa * x * x1 * x2 + aa * x1 ^ 3 + aa * x2 ^ 3 + + The correction term is dx and bb + aa = -1/3! + */ +#define TAYLOR_SLOW(x0, dx, cor) \ +({ \ + static const double th2_36 = 206158430208.0; /* 1.5*2**37 */ \ + double xx = (x0) * (x0); \ + double x1 = ((x0) + th2_36) - th2_36; \ + double y = aa * x1 * x1 * x1; \ + double r = (x0) + y; \ + double x2 = ((x0) - x1) + (dx); \ + double t = (((POLYNOMIAL2 (xx) + bb) * xx + 3.0 * aa * x1 * x2) \ + * (x0) + aa * x2 * x2 * x2 + (dx)); \ + t = (((x0) - r) + y) + t; \ + double res = r + t; \ + (cor) = (r - res) + t; \ + res; \ +}) + +#define SINCOS_TABLE_LOOKUP(u, sn, ssn, cs, ccs) \ +({ \ + int4 k = u.i[LOW_HALF] << 2; \ + sn = __sincostab.x[k]; \ + ssn = __sincostab.x[k + 1]; \ + cs = __sincostab.x[k + 2]; \ + ccs = __sincostab.x[k + 3]; \ +}) + #ifndef SECTION # define SECTION #endif @@ -72,12 +124,12 @@ static const double cs4 = -4.16666666666664434524222570944589E-02, cs6 = 1.38888874007937613028114285595617E-03; +static const double t22 = 0x1.8p22; + void __dubsin (double x, double dx, double w[]); void __docos (double x, double dx, double w[]); -double __mpsin (double x, double dx); -double __mpcos (double x, double dx); -double __mpsin1 (double x); -double __mpcos1 (double x); +double __mpsin (double x, double dx, bool reduce_range); +double __mpcos (double x, double dx, bool reduce_range); static double slow (double x); static double slow1 (double x); static double slow2 (double x); @@ -93,6 +145,39 @@ static double csloww (double x, double dx, double orig); static double csloww1 (double x, double dx, double orig); static double csloww2 (double x, double dx, double orig, int n); +/* Reduce range of X and compute sin of a + da. K is the amount by which to + rotate the quadrants. This allows us to use the same routine to compute cos + by simply rotating the quadrants by 1. */ +static inline double +__always_inline +reduce_and_compute (double x, double a, double da, unsigned int k) +{ + double retval = 0; + unsigned int n = __branred (x, &a, &da); + k = (n + k) % 4; + switch (k) + { + case 0: + if (a * a < 0.01588) + retval = bsloww (a, da, x, n); + else + retval = bsloww1 (a, da, x, n); + break; + case 2: + if (a * a < 0.01588) + retval = bsloww (-a, -da, x, n); + else + retval = bsloww1 (-a, -da, x, n); + break; + + case 1: + case 3: + retval = bsloww2 (a, da, x, n); + break; + } + return retval; +} + /*******************************************************************/ /* An ultimate sin routine. Given an IEEE double machine number x */ /* it computes the correctly rounded (to nearest) value of sin(x) */ @@ -113,81 +198,71 @@ __sin (double x) m = u.i[HIGH_HALF]; k = 0x7fffffff & m; /* no sign */ if (k < 0x3e500000) /* if x->0 =>sin(x)=x */ - { - retval = x; - goto ret; - } + retval = x; /*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/ else if (k < 0x3fd00000) { xx = x * x; - /*Taylor series. */ - t = (((((s5.x * xx + s4.x) * xx + s3.x) * xx + s2.x) * xx + s1.x) - * (xx * x)); + /* Taylor series. */ + t = POLYNOMIAL (xx) * (xx * x); res = x + t; cor = (x - res) + t; retval = (res == res + 1.07 * cor) ? res : slow (x); - goto ret; } /* else if (k < 0x3fd00000) */ /*---------------------------- 0.25<|x|< 0.855469---------------------- */ else if (k < 0x3feb6000) { - u.x = (m > 0) ? big.x + x : big.x - x; - y = (m > 0) ? x - (u.x - big.x) : x + (u.x - big.x); + u.x = (m > 0) ? big + x : big - x; + y = (m > 0) ? x - (u.x - big) : x + (u.x - big); xx = y * y; s = y + y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = (m > 0) ? __sincostab.x[k] : -__sincostab.x[k]; - ssn = (m > 0) ? __sincostab.x[k + 1] : -__sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); + if (m <= 0) + { + sn = -sn; + ssn = -ssn; + } cor = (ssn + s * ccs - sn * c) + cs * s; res = sn + cor; cor = (sn - res) + cor; retval = (res == res + 1.096 * cor) ? res : slow1 (x); - goto ret; } /* else if (k < 0x3feb6000) */ /*----------------------- 0.855469 <|x|<2.426265 ----------------------*/ else if (k < 0x400368fd) { - y = (m > 0) ? hp0.x - x : hp0.x + x; + y = (m > 0) ? hp0 - x : hp0 + x; if (y >= 0) { - u.x = big.x + y; - y = (y - (u.x - big.x)) + hp1.x; + u.x = big + y; + y = (y - (u.x - big)) + hp1; } else { - u.x = big.x - y; - y = (-hp1.x) - (y + (u.x - big.x)); + u.x = big - y; + y = (-hp1) - (y + (u.x - big)); } xx = y * y; s = y + y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); cor = (ccs - s * ssn - cs * c) - sn * s; res = cs + cor; cor = (cs - res) + cor; retval = (res == res + 1.020 * cor) ? ((m > 0) ? res : -res) : slow2 (x); - goto ret; } /* else if (k < 0x400368fd) */ /*-------------------------- 2.426265<|x|< 105414350 ----------------------*/ else if (k < 0x419921FB) { - t = (x * hpinv.x + toint.x); - xn = t - toint.x; + t = (x * hpinv + toint); + xn = t - toint; v.x = t; - y = (x - xn * mp1.x) - xn * mp2.x; + y = (x - xn * mp1) - xn * mp2; n = v.i[LOW_HALF] & 3; - da = xn * mp3.x; + da = xn * mp3; a = y - da; da = (y - a) - da; eps = ABS (x) * 1.2e-30; @@ -204,14 +279,10 @@ __sin (double x) } if (xx < 0.01588) { - /*Taylor series */ - t = (((((s5.x * xx + s4.x) * xx + s3.x) * xx + s2.x) * xx - + s1.x) * a - 0.5 * da) * xx + da; - res = a + t; - cor = (a - res) + t; + /* Taylor series. */ + res = TAYLOR_SIN (xx, a, da, cor); cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps; retval = (res == res + cor) ? res : sloww (a, da, x); - goto ret; } else { @@ -227,23 +298,18 @@ __sin (double x) t = -a; db = -da; } - u.x = big.x + t; - y = t - (u.x - big.x); + u.x = big + t; + y = t - (u.x - big); xx = y * y; s = y + (db + y * xx * (sn3 + xx * sn5)); c = y * db + xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); cor = (ssn + s * ccs - sn * c) + cs * s; res = sn + cor; cor = (sn - res) + cor; cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps; retval = ((res == res + cor) ? ((m) ? res : -res) : sloww1 (a, da, x)); - goto ret; } break; @@ -254,14 +320,10 @@ __sin (double x) a = -a; da = -da; } - u.x = big.x + a; - y = a - (u.x - big.x) + da; + u.x = big + a; + y = a - (u.x - big) + da; xx = y * y; - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); s = y + y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); cor = (ccs - s * ssn - cs * c) - sn * s; @@ -270,27 +332,24 @@ __sin (double x) cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps; retval = ((res == res + cor) ? ((n & 2) ? -res : res) : sloww2 (a, da, x, n)); - goto ret; - break; } - } /* else if (k < 0x419921FB ) */ /*---------------------105414350 <|x|< 281474976710656 --------------------*/ else if (k < 0x42F00000) { - t = (x * hpinv.x + toint.x); - xn = t - toint.x; + t = (x * hpinv + toint); + xn = t - toint; v.x = t; xn1 = (xn + 8.0e22) - 8.0e22; xn2 = xn - xn1; - y = ((((x - xn1 * mp1.x) - xn1 * mp2.x) - xn2 * mp1.x) - xn2 * mp2.x); + y = ((((x - xn1 * mp1) - xn1 * mp2) - xn2 * mp1) - xn2 * mp2); n = v.i[LOW_HALF] & 3; - da = xn1 * pp3.x; + da = xn1 * pp3; t = y - da; da = (y - t) - da; - da = (da - xn2 * pp3.x) - xn * pp4.x; + da = (da - xn2 * pp3) - xn * pp4; a = t + da; da = (t - a) + da; eps = 1.0e-24; @@ -307,14 +366,10 @@ __sin (double x) } if (xx < 0.01588) { - /* Taylor series */ - t = (((((s5.x * xx + s4.x) * xx + s3.x) * xx + s2.x) * xx - + s1.x) * a - 0.5 * da) * xx + da; - res = a + t; - cor = (a - res) + t; + /* Taylor series. */ + res = TAYLOR_SIN (xx, a, da, cor); cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps; retval = (res == res + cor) ? res : bsloww (a, da, x, n); - goto ret; } else { @@ -330,23 +385,18 @@ __sin (double x) t = -a; db = -da; } - u.x = big.x + t; - y = t - (u.x - big.x); + u.x = big + t; + y = t - (u.x - big); xx = y * y; s = y + (db + y * xx * (sn3 + xx * sn5)); c = y * db + xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); cor = (ssn + s * ccs - sn * c) + cs * s; res = sn + cor; cor = (sn - res) + cor; cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps; retval = ((res == res + cor) ? ((m) ? res : -res) : bsloww1 (a, da, x, n)); - goto ret; } break; @@ -357,14 +407,10 @@ __sin (double x) a = -a; da = -da; } - u.x = big.x + a; - y = a - (u.x - big.x) + da; + u.x = big + a; + y = a - (u.x - big) + da; xx = y * y; - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); s = y + y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); cor = (ccs - s * ssn - cs * c) - sn * s; @@ -373,40 +419,13 @@ __sin (double x) cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps; retval = ((res == res + cor) ? ((n & 2) ? -res : res) : bsloww2 (a, da, x, n)); - goto ret; - break; } } /* else if (k < 0x42F00000 ) */ /* -----------------281474976710656 <|x| <2^1024----------------------------*/ else if (k < 0x7ff00000) - { - n = __branred (x, &a, &da); - switch (n) - { - case 0: - 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) - retval = bsloww (-a, -da, x, n); - else - retval = bsloww1 (-a, -da, x, n); - goto ret; - break; - - case 1: - case 3: - retval = bsloww2 (a, da, x, n); - goto ret; - break; - } - } /* else if (k < 0x7ff00000 ) */ + retval = reduce_and_compute (x, a, da, 0); /*--------------------- |x| > 2^1024 ----------------------------------*/ else @@ -414,10 +433,8 @@ __sin (double x) if (k == 0x7ff00000 && u.i[LOW_HALF] == 0) __set_errno (EDOM); retval = x / x; - goto ret; } -ret: return retval; } @@ -444,47 +461,36 @@ __cos (double x) m = u.i[HIGH_HALF]; k = 0x7fffffff & m; + /* |x|<2^-27 => cos(x)=1 */ if (k < 0x3e400000) - { - retval = 1.0; - goto ret; - } /* |x|<2^-27 => cos(x)=1 */ + retval = 1.0; else if (k < 0x3feb6000) { /* 2^-27 < |x| < 0.855469 */ y = ABS (x); - u.x = big.x + y; - y = y - (u.x - big.x); + u.x = big + y; + y = y - (u.x - big); xx = y * y; s = y + y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); cor = (ccs - s * ssn - cs * c) - sn * s; res = cs + cor; cor = (cs - res) + cor; retval = (res == res + 1.020 * cor) ? res : cslow2 (x); - goto ret; } /* else if (k < 0x3feb6000) */ else if (k < 0x400368fd) { /* 0.855469 <|x|<2.426265 */ ; - y = hp0.x - ABS (x); - a = y + hp1.x; - da = (y - a) + hp1.x; + y = hp0 - ABS (x); + a = y + hp1; + da = (y - a) + hp1; xx = a * a; if (xx < 0.01588) { - t = (((((s5.x * xx + s4.x) * xx + s3.x) * xx + s2.x) * xx + s1.x) - * a - 0.5 * da) * xx + da; - res = a + t; - cor = (a - res) + t; + res = TAYLOR_SIN (xx, a, da, cor); cor = (cor > 0) ? 1.02 * cor + 1.0e-31 : 1.02 * cor - 1.0e-31; retval = (res == res + cor) ? res : csloww (a, da, x); - goto ret; } else { @@ -500,23 +506,18 @@ __cos (double x) t = -a; db = -da; } - u.x = big.x + t; - y = t - (u.x - big.x); + u.x = big + t; + y = t - (u.x - big); xx = y * y; s = y + (db + y * xx * (sn3 + xx * sn5)); c = y * db + xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); cor = (ssn + s * ccs - sn * c) + cs * s; res = sn + cor; cor = (sn - res) + cor; cor = (cor > 0) ? 1.035 * cor + 1.0e-31 : 1.035 * cor - 1.0e-31; retval = ((res == res + cor) ? ((m) ? res : -res) : csloww1 (a, da, x)); - goto ret; } } /* else if (k < 0x400368fd) */ @@ -524,12 +525,12 @@ __cos (double x) else if (k < 0x419921FB) { /* 2.426265<|x|< 105414350 */ - t = (x * hpinv.x + toint.x); - xn = t - toint.x; + t = (x * hpinv + toint); + xn = t - toint; v.x = t; - y = (x - xn * mp1.x) - xn * mp2.x; + y = (x - xn * mp1) - xn * mp2; n = v.i[LOW_HALF] & 3; - da = xn * mp3.x; + da = xn * mp3; a = y - da; da = (y - a) - da; eps = ABS (x) * 1.2e-30; @@ -546,13 +547,9 @@ __cos (double x) } if (xx < 0.01588) { - t = (((((s5.x * xx + s4.x) * xx + s3.x) * xx + s2.x) * xx - + s1.x) * a - 0.5 * da) * xx + da; - res = a + t; - cor = (a - res) + t; + res = TAYLOR_SIN (xx, a, da, cor); cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps; retval = (res == res + cor) ? res : csloww (a, da, x); - goto ret; } else { @@ -568,23 +565,18 @@ __cos (double x) t = -a; db = -da; } - u.x = big.x + t; - y = t - (u.x - big.x); + u.x = big + t; + y = t - (u.x - big); xx = y * y; s = y + (db + y * xx * (sn3 + xx * sn5)); c = y * db + xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); cor = (ssn + s * ccs - sn * c) + cs * s; res = sn + cor; cor = (sn - res) + cor; cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps; retval = ((res == res + cor) ? ((m) ? res : -res) : csloww1 (a, da, x)); - goto ret; } break; @@ -595,14 +587,10 @@ __cos (double x) a = -a; da = -da; } - u.x = big.x + a; - y = a - (u.x - big.x) + da; + u.x = big + a; + y = a - (u.x - big) + da; xx = y * y; - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); s = y + y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); cor = (ccs - s * ssn - cs * c) - sn * s; @@ -611,25 +599,23 @@ __cos (double x) cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps; retval = ((res == res + cor) ? ((n) ? -res : res) : csloww2 (a, da, x, n)); - goto ret; - break; } } /* else if (k < 0x419921FB ) */ else if (k < 0x42F00000) { - t = (x * hpinv.x + toint.x); - xn = t - toint.x; + t = (x * hpinv + toint); + xn = t - toint; v.x = t; xn1 = (xn + 8.0e22) - 8.0e22; xn2 = xn - xn1; - y = ((((x - xn1 * mp1.x) - xn1 * mp2.x) - xn2 * mp1.x) - xn2 * mp2.x); + y = ((((x - xn1 * mp1) - xn1 * mp2) - xn2 * mp1) - xn2 * mp2); n = v.i[LOW_HALF] & 3; - da = xn1 * pp3.x; + da = xn1 * pp3; t = y - da; da = (y - t) - da; - da = (da - xn2 * pp3.x) - xn * pp4.x; + da = (da - xn2 * pp3) - xn * pp4; a = t + da; da = (t - a) + da; eps = 1.0e-24; @@ -646,13 +632,9 @@ __cos (double x) } if (xx < 0.01588) { - t = (((((s5.x * xx + s4.x) * xx + s3.x) * xx + s2.x) * xx - + s1.x) * a - 0.5 * da) * xx + da; - res = a + t; - cor = (a - res) + t; + res = TAYLOR_SIN (xx, a, da, cor); cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps; retval = (res == res + cor) ? res : bsloww (a, da, x, n); - goto ret; } else { @@ -668,23 +650,18 @@ __cos (double x) t = -a; db = -da; } - u.x = big.x + t; - y = t - (u.x - big.x); + u.x = big + t; + y = t - (u.x - big); xx = y * y; s = y + (db + y * xx * (sn3 + xx * sn5)); c = y * db + xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); cor = (ssn + s * ccs - sn * c) + cs * s; res = sn + cor; cor = (sn - res) + cor; cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps; retval = ((res == res + cor) ? ((m) ? res : -res) : bsloww1 (a, da, x, n)); - goto ret; } break; @@ -695,14 +672,10 @@ __cos (double x) a = -a; da = -da; } - u.x = big.x + a; - y = a - (u.x - big.x) + da; + u.x = big + a; + y = a - (u.x - big) + da; xx = y * y; - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); s = y + y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); cor = (ccs - s * ssn - cs * c) - sn * s; @@ -711,49 +684,21 @@ __cos (double x) cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps; retval = ((res == res + cor) ? ((n) ? -res : res) : bsloww2 (a, da, x, n)); - goto ret; break; } } /* else if (k < 0x42F00000 ) */ + /* 281474976710656 <|x| <2^1024 */ else if (k < 0x7ff00000) - { /* 281474976710656 <|x| <2^1024 */ - - n = __branred (x, &a, &da); - switch (n) - { - case 1: - 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) - retval = bsloww (a, da, x, n); - else - retval = bsloww1 (a, da, x, n); - goto ret; - break; - - case 0: - case 2: - retval = bsloww2 (a, da, x, n); - goto ret; - break; - } - } /* else if (k < 0x7ff00000 ) */ + retval = reduce_and_compute (x, a, da, 1); else { if (k == 0x7ff00000 && u.i[LOW_HALF] == 0) __set_errno (EDOM); retval = x / x; /* |x| > 2^1024 */ - goto ret; } -ret: return retval; } @@ -766,18 +711,8 @@ static double SECTION slow (double x) { - static const double th2_36 = 206158430208.0; /* 1.5*2**37 */ - double y, x1, x2, xx, r, t, res, cor, w[2]; - x1 = (x + th2_36) - th2_36; - y = aa.x * x1 * x1 * x1; - r = x + y; - x2 = x - x1; - xx = x * x; - t = (((((s5.x * xx + s4.x) * xx + s3.x) * xx + s2.x) * xx + bb.x) * xx - + 3.0 * aa.x * x1 * x2) * x + aa.x * x2 * x2 * x2; - t = ((x - r) + y) + t; - res = r + t; - cor = (r - res) + t; + double res, cor, w[2]; + res = TAYLOR_SLOW (x, 0, cor); if (res == res + 1.0007 * cor) return res; else @@ -786,12 +721,12 @@ slow (double x) if (w[0] == w[0] + 1.000000001 * w[1]) return (x > 0) ? w[0] : -w[0]; else - return (x > 0) ? __mpsin (x, 0) : -__mpsin (-x, 0); + return (x > 0) ? __mpsin (x, 0, false) : -__mpsin (-x, 0, false); } } /*******************************************************************************/ -/* Routine compute sin(x) for 0.25<|x|< 0.855469 by __sincostab.tbl and Taylor */ +/* Routine compute sin(x) for 0.25<|x|< 0.855469 by __sincostab.tbl and Taylor */ /* and if result still doesn't accurate enough by mpsin or dubsin */ /*******************************************************************************/ @@ -801,19 +736,13 @@ slow1 (double x) { mynumber u; double sn, ssn, cs, ccs, s, c, w[2], y, y1, y2, c1, c2, xx, cor, res; - static const double t22 = 6291456.0; - int4 k; y = ABS (x); - u.x = big.x + y; - y = y - (u.x - big.x); + u.x = big + y; + y = y - (u.x - big); xx = y * y; s = y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; /* Data */ - ssn = __sincostab.x[k + 1]; /* from */ - cs = __sincostab.x[k + 2]; /* tables */ - ccs = __sincostab.x[k + 3]; /* __sincostab.tbl */ + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); y1 = (y + t22) - t22; y2 = y - y1; c1 = (cs + t22) - t22; @@ -831,7 +760,7 @@ slow1 (double x) if (w[0] == w[0] + 1.000000005 * w[1]) return (x > 0) ? w[0] : -w[0]; else - return (x > 0) ? __mpsin (x, 0) : -__mpsin (-x, 0); + return (x > 0) ? __mpsin (x, 0, false) : -__mpsin (-x, 0, false); } } @@ -845,30 +774,25 @@ slow2 (double x) { mynumber u; double sn, ssn, cs, ccs, s, c, w[2], y, y1, y2, e1, e2, xx, cor, res, del; - static const double t22 = 6291456.0; - int4 k; + y = ABS (x); - y = hp0.x - y; + y = hp0 - y; if (y >= 0) { - u.x = big.x + y; - y = y - (u.x - big.x); - del = hp1.x; + u.x = big + y; + y = y - (u.x - big); + del = hp1; } else { - u.x = big.x - y; - y = -(y + (u.x - big.x)); - del = -hp1.x; + u.x = big - y; + y = -(y + (u.x - big)); + del = -hp1; } xx = y * y; s = y * xx * (sn3 + xx * sn5); c = y * del + xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); y1 = (y + t22) - t22; y2 = (y - y1) + del; e1 = (sn + t22) - t22; @@ -882,14 +806,14 @@ slow2 (double x) return (x > 0) ? res : -res; else { - y = ABS (x) - hp0.x; - y1 = y - hp1.x; - y2 = (y - y1) - hp1.x; + y = ABS (x) - hp0; + y1 = y - hp1; + y2 = (y - y1) - hp1; __docos (y1, y2, w); if (w[0] == w[0] + 1.000000005 * w[1]) return (x > 0) ? w[0] : -w[0]; else - return (x > 0) ? __mpsin (x, 0) : -__mpsin (-x, 0); + return (x > 0) ? __mpsin (x, 0, false) : -__mpsin (-x, 0, false); } } @@ -905,28 +829,15 @@ static double SECTION sloww (double x, double dx, double orig) { - static const double th2_36 = 206158430208.0; /* 1.5*2**37 */ - double y, x1, x2, xx, r, t, res, cor, w[2], a, da, xn; - union - { - int4 i[2]; - double x; - } v; + double y, t, res, cor, w[2], a, da, xn; + mynumber v; int4 n; - x1 = (x + th2_36) - th2_36; - y = aa.x * x1 * x1 * x1; - r = x + y; - x2 = (x - x1) + dx; - xx = x * x; - t = (((((s5.x * xx + s4.x) * xx + s3.x) * xx + s2.x) * xx + bb.x) * xx - + 3.0 * aa.x * x1 * x2) * x + aa.x * x2 * x2 * x2 + dx; - t = ((x - r) + y) + t; - res = r + t; - cor = (r - res) + t; - cor = - (cor > - 0) ? 1.0005 * cor + ABS (orig) * 3.1e-30 : 1.0005 * cor - - ABS (orig) * 3.1e-30; + res = TAYLOR_SLOW (x, dx, cor); + if (cor > 0) + cor = 1.0005 * cor + ABS (orig) * 3.1e-30; + else + cor = 1.0005 * cor - ABS (orig) * 3.1e-30; + if (res == res + cor) return res; else @@ -941,15 +852,15 @@ sloww (double x, double dx, double orig) return (x > 0) ? w[0] : -w[0]; else { - t = (orig * hpinv.x + toint.x); - xn = t - toint.x; + t = (orig * hpinv + toint); + xn = t - toint; v.x = t; - y = (orig - xn * mp1.x) - xn * mp2.x; + y = (orig - xn * mp1) - xn * mp2; n = v.i[LOW_HALF] & 3; - da = xn * pp3.x; + da = xn * pp3; t = y - da; da = (y - t) - da; - y = xn * pp4.x; + y = xn * pp4; a = t - y; da = ((t - a) - y) + da; if (n & 2) @@ -966,7 +877,7 @@ sloww (double x, double dx, double orig) if (w[0] == w[0] + cor) return (a > 0) ? w[0] : -w[0]; else - return __mpsin1 (orig); + return __mpsin (orig, 0, true); } } } @@ -984,21 +895,15 @@ sloww1 (double x, double dx, double orig) { mynumber u; double sn, ssn, cs, ccs, s, c, w[2], y, y1, y2, c1, c2, xx, cor, res; - static const double t22 = 6291456.0; - int4 k; y = ABS (x); - u.x = big.x + y; - y = y - (u.x - big.x); + u.x = big + y; + y = y - (u.x - big); dx = (x > 0) ? dx : -dx; xx = y * y; s = y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); y1 = (y + t22) - t22; y2 = (y - y1) + dx; c1 = (cs + t22) - t22; @@ -1028,7 +933,7 @@ sloww1 (double x, double dx, double orig) if (w[0] == w[0] + cor) return (x > 0) ? w[0] : -w[0]; else - return __mpsin1 (orig); + return __mpsin (orig, 0, true); } } @@ -1045,21 +950,15 @@ sloww2 (double x, double dx, double orig, int n) { mynumber u; double sn, ssn, cs, ccs, s, c, w[2], y, y1, y2, e1, e2, xx, cor, res; - static const double t22 = 6291456.0; - int4 k; y = ABS (x); - u.x = big.x + y; - y = y - (u.x - big.x); + u.x = big + y; + y = y - (u.x - big); dx = (x > 0) ? dx : -dx; xx = y * y; s = y * xx * (sn3 + xx * sn5); c = y * dx + xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); y1 = (y + t22) - t22; y2 = (y - y1) + dx; @@ -1090,7 +989,7 @@ sloww2 (double x, double dx, double orig, int n) if (w[0] == w[0] + cor) return (n & 2) ? -w[0] : w[0]; else - return __mpsin1 (orig); + return __mpsin (orig, 0, true); } } @@ -1106,19 +1005,9 @@ static double SECTION bsloww (double x, double dx, double orig, int n) { - static const double th2_36 = 206158430208.0; /* 1.5*2**37 */ - double y, x1, x2, xx, r, t, res, cor, w[2]; - - x1 = (x + th2_36) - th2_36; - y = aa.x * x1 * x1 * x1; - r = x + y; - x2 = (x - x1) + dx; - xx = x * x; - t = (((((s5.x * xx + s4.x) * xx + s3.x) * xx + s2.x) * xx + bb.x) * xx - + 3.0 * aa.x * x1 * x2) * x + aa.x * x2 * x2 * x2 + dx; - t = ((x - r) + y) + t; - res = r + t; - cor = (r - res) + t; + double res, cor, w[2]; + + res = TAYLOR_SLOW (x, dx, cor); cor = (cor > 0) ? 1.0005 * cor + 1.1e-24 : 1.0005 * cor - 1.1e-24; if (res == res + cor) return res; @@ -1132,7 +1021,7 @@ bsloww (double x, double dx, double orig, int n) if (w[0] == w[0] + cor) return (x > 0) ? w[0] : -w[0]; else - return (n & 1) ? __mpcos1 (orig) : __mpsin1 (orig); + return (n & 1) ? __mpcos (orig, 0, true) : __mpsin (orig, 0, true); } } @@ -1149,21 +1038,15 @@ bsloww1 (double x, double dx, double orig, int n) { mynumber u; double sn, ssn, cs, ccs, s, c, w[2], y, y1, y2, c1, c2, xx, cor, res; - static const double t22 = 6291456.0; - int4 k; y = ABS (x); - u.x = big.x + y; - y = y - (u.x - big.x); + u.x = big + y; + y = y - (u.x - big); dx = (x > 0) ? dx : -dx; xx = y * y; s = y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); y1 = (y + t22) - t22; y2 = (y - y1) + dx; c1 = (cs + t22) - t22; @@ -1188,7 +1071,7 @@ bsloww1 (double x, double dx, double orig, int n) if (w[0] == w[0] + cor) return (x > 0) ? w[0] : -w[0]; else - return (n & 1) ? __mpcos1 (orig) : __mpsin1 (orig); + return (n & 1) ? __mpcos (orig, 0, true) : __mpsin (orig, 0, true); } } @@ -1205,21 +1088,15 @@ bsloww2 (double x, double dx, double orig, int n) { mynumber u; double sn, ssn, cs, ccs, s, c, w[2], y, y1, y2, e1, e2, xx, cor, res; - static const double t22 = 6291456.0; - int4 k; y = ABS (x); - u.x = big.x + y; - y = y - (u.x - big.x); + u.x = big + y; + y = y - (u.x - big); dx = (x > 0) ? dx : -dx; xx = y * y; s = y * xx * (sn3 + xx * sn5); c = y * dx + xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); y1 = (y + t22) - t22; y2 = (y - y1) + dx; @@ -1245,7 +1122,7 @@ bsloww2 (double x, double dx, double orig, int n) if (w[0] == w[0] + cor) return (n & 2) ? -w[0] : w[0]; else - return (n & 1) ? __mpsin1 (orig) : __mpcos1 (orig); + return (n & 1) ? __mpsin (orig, 0, true) : __mpcos (orig, 0, true); } } @@ -1260,20 +1137,14 @@ cslow2 (double x) { mynumber u; double sn, ssn, cs, ccs, s, c, w[2], y, y1, y2, e1, e2, xx, cor, res; - static const double t22 = 6291456.0; - int4 k; y = ABS (x); - u.x = big.x + y; - y = y - (u.x - big.x); + u.x = big + y; + y = y - (u.x - big); xx = y * y; s = y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); y1 = (y + t22) - t22; y2 = y - y1; e1 = (sn + t22) - t22; @@ -1292,7 +1163,7 @@ cslow2 (double x) if (w[0] == w[0] + 1.000000005 * w[1]) return w[0]; else - return __mpcos (x, 0); + return __mpcos (x, 0, false); } } @@ -1308,26 +1179,12 @@ static double SECTION csloww (double x, double dx, double orig) { - static const double th2_36 = 206158430208.0; /* 1.5*2**37 */ - double y, x1, x2, xx, r, t, res, cor, w[2], a, da, xn; - union - { - int4 i[2]; - double x; - } v; + double y, t, res, cor, w[2], a, da, xn; + mynumber v; int4 n; - x1 = (x + th2_36) - th2_36; - y = aa.x * x1 * x1 * x1; - r = x + y; - x2 = (x - x1) + dx; - xx = x * x; /* Taylor series */ - t = (((((s5.x * xx + s4.x) * xx + s3.x) * xx + s2.x) * xx + bb.x) * xx - + 3.0 * aa.x * x1 * x2) * x + aa.x * x2 * x2 * x2 + dx; - t = ((x - r) + y) + t; - res = r + t; - cor = (r - res) + t; + t = TAYLOR_SLOW (x, dx, cor); if (cor > 0) cor = 1.0005 * cor + ABS (orig) * 3.1e-30; @@ -1349,15 +1206,15 @@ csloww (double x, double dx, double orig) return (x > 0) ? w[0] : -w[0]; else { - t = (orig * hpinv.x + toint.x); - xn = t - toint.x; + t = (orig * hpinv + toint); + xn = t - toint; v.x = t; - y = (orig - xn * mp1.x) - xn * mp2.x; + y = (orig - xn * mp1) - xn * mp2; n = v.i[LOW_HALF] & 3; - da = xn * pp3.x; + da = xn * pp3; t = y - da; da = (y - t) - da; - y = xn * pp4.x; + y = xn * pp4; a = t - y; da = ((t - a) - y) + da; if (n == 1) @@ -1375,7 +1232,7 @@ csloww (double x, double dx, double orig) if (w[0] == w[0] + cor) return (a > 0) ? w[0] : -w[0]; else - return __mpcos1 (orig); + return __mpcos (orig, 0, true); } } } @@ -1393,21 +1250,15 @@ csloww1 (double x, double dx, double orig) { mynumber u; double sn, ssn, cs, ccs, s, c, w[2], y, y1, y2, c1, c2, xx, cor, res; - static const double t22 = 6291456.0; - int4 k; y = ABS (x); - u.x = big.x + y; - y = y - (u.x - big.x); + u.x = big + y; + y = y - (u.x - big); dx = (x > 0) ? dx : -dx; xx = y * y; s = y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); y1 = (y + t22) - t22; y2 = (y - y1) + dx; c1 = (cs + t22) - t22; @@ -1435,7 +1286,7 @@ csloww1 (double x, double dx, double orig) if (w[0] == w[0] + cor) return (x > 0) ? w[0] : -w[0]; else - return __mpcos1 (orig); + return __mpcos (orig, 0, true); } } @@ -1453,21 +1304,15 @@ csloww2 (double x, double dx, double orig, int n) { mynumber u; double sn, ssn, cs, ccs, s, c, w[2], y, y1, y2, e1, e2, xx, cor, res; - static const double t22 = 6291456.0; - int4 k; y = ABS (x); - u.x = big.x + y; - y = y - (u.x - big.x); + u.x = big + y; + y = y - (u.x - big); dx = (x > 0) ? dx : -dx; xx = y * y; s = y * xx * (sn3 + xx * sn5); c = y * dx + xx * (cs2 + xx * (cs4 + xx * cs6)); - k = u.i[LOW_HALF] << 2; - sn = __sincostab.x[k]; - ssn = __sincostab.x[k + 1]; - cs = __sincostab.x[k + 2]; - ccs = __sincostab.x[k + 3]; + SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); y1 = (y + t22) - t22; y2 = (y - y1) + dx; @@ -1496,7 +1341,7 @@ csloww2 (double x, double dx, double orig, int n) if (w[0] == w[0] + cor) return (n) ? -w[0] : w[0]; else - return __mpcos1 (orig); + return __mpcos (orig, 0, true); } } diff --git a/sysdeps/ieee754/dbl-64/s_sincos.c b/sysdeps/ieee754/dbl-64/s_sincos.c index b6d5432f46..01d1bdf977 100644 --- a/sysdeps/ieee754/dbl-64/s_sincos.c +++ b/sysdeps/ieee754/dbl-64/s_sincos.c @@ -32,7 +32,7 @@ __sincos (double x, double *sinx, double *cosx) /* |x| ~< pi/4 */ ix &= 0x7fffffff; - if (ix>=0x7ff00000) + if (ix >= 0x7ff00000) { /* sin(Inf or NaN) is NaN */ *sinx = *cosx = x - x; diff --git a/sysdeps/ieee754/dbl-64/s_tan.c b/sysdeps/ieee754/dbl-64/s_tan.c index 54f863e544..09db096d05 100644 --- a/sysdeps/ieee754/dbl-64/s_tan.c +++ b/sysdeps/ieee754/dbl-64/s_tan.c @@ -41,6 +41,7 @@ #include <math.h> #include <math_private.h> #include <fenv.h> +#include <stap-probe.h> #ifndef SECTION # define SECTION @@ -58,8 +59,8 @@ tan (double x) int ux, i, n; double a, da, a2, b, db, c, dc, c1, cc1, c2, cc2, c3, cc3, fi, ffi, gi, pz, - s, sy, t, t1, t2, t3, t4, t7, t8, t9, t10, w, x2, xn, xx2, y, ya, yya, z0, - z, zz, z2, zz2; + s, sy, t, t1, t2, t3, t4, t7, t8, t9, t10, w, x2, xn, xx2, y, ya, + yya, z0, z, zz, z2, zz2; #ifndef DLA_FMS double t5, t6; #endif @@ -97,7 +98,6 @@ tan (double x) /* (II) The case 1.259e-8 < abs(x) <= 0.0608 */ if (w <= g2.d) { - /* First stage */ x2 = x * x; @@ -149,7 +149,6 @@ tan (double x) /* (III) The case 0.0608 < abs(x) <= 0.787 */ if (w <= g3.d) { - /* First stage */ i = ((int) (mfftnhf.d + TWO8 * w)); z = w - xfg[i][0].d; @@ -376,7 +375,7 @@ tan (double x) /* Second stage */ ffi = xfg[i][3].d; EADD (z0, yya, z, zz) - MUL2 (z, zz, z, zz, z2, zz2, t1, t2, t3, t4, t5, t6, t7, t8); + MUL2 (z, zz, z, zz, z2, zz2, t1, t2, t3, t4, t5, t6, t7, t8); c1 = z2 * (a7.d + z2 * (a9.d + z2 * a11.d)); ADD2 (a5.d, aa5.d, c1, 0.0, c2, cc2, t1, t2); MUL2 (z2, zz2, c2, cc2, c1, cc1, t1, t2, t3, t4, t5, t6, t7, t8); @@ -838,6 +837,7 @@ tanMp (double x) p = 32; __mptan (x, &mpy, p); __mp_dbl (&mpy, &y, p); + LIBC_PROBE (slowtan, 2, &x, &y); return y; } diff --git a/sysdeps/ieee754/dbl-64/s_tanh.c b/sysdeps/ieee754/dbl-64/s_tanh.c index ded0d6025d..23cfcdead5 100644 --- a/sysdeps/ieee754/dbl-64/s_tanh.c +++ b/sysdeps/ieee754/dbl-64/s_tanh.c @@ -41,41 +41,51 @@ static char rcsid[] = "$NetBSD: s_tanh.c,v 1.7 1995/05/10 20:48:22 jtc Exp $"; #include <math.h> #include <math_private.h> -static const double one=1.0, two=2.0, tiny = 1.0e-300; +static const double one = 1.0, two = 2.0, tiny = 1.0e-300; -double __tanh(double x) +double +__tanh (double x) { - double t,z; - int32_t jx,ix,lx; + double t, z; + int32_t jx, ix, lx; - /* High word of |x|. */ - EXTRACT_WORDS(jx,lx,x); - ix = jx&0x7fffffff; + /* High word of |x|. */ + EXTRACT_WORDS (jx, lx, x); + ix = jx & 0x7fffffff; - /* x is INF or NaN */ - if(ix>=0x7ff00000) { - if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ - else return one/x-one; /* tanh(NaN) = NaN */ - } + /* x is INF or NaN */ + if (ix >= 0x7ff00000) + { + if (jx >= 0) + return one / x + one; /* tanh(+-inf)=+-1 */ + else + return one / x - one; /* tanh(NaN) = NaN */ + } - /* |x| < 22 */ - if (ix < 0x40360000) { /* |x|<22 */ - if ((ix | lx) == 0) - return x; /* x == +-0 */ - if (ix<0x3c800000) /* |x|<2**-55 */ - return x*(one+x); /* tanh(small) = small */ - if (ix>=0x3ff00000) { /* |x|>=1 */ - t = __expm1(two*fabs(x)); - z = one - two/(t+two); - } else { - t = __expm1(-two*fabs(x)); - z= -t/(t+two); - } - /* |x| > 22, return +-1 */ - } else { - z = one - tiny; /* raised inexact flag */ + /* |x| < 22 */ + if (ix < 0x40360000) /* |x|<22 */ + { + if ((ix | lx) == 0) + return x; /* x == +-0 */ + if (ix < 0x3c800000) /* |x|<2**-55 */ + return x * (one + x); /* tanh(small) = small */ + if (ix >= 0x3ff00000) /* |x|>=1 */ + { + t = __expm1 (two * fabs (x)); + z = one - two / (t + two); + } + else + { + t = __expm1 (-two * fabs (x)); + z = -t / (t + two); } - return (jx>=0)? z: -z; + /* |x| > 22, return +-1 */ + } + else + { + z = one - tiny; /* raised inexact flag */ + } + return (jx >= 0) ? z : -z; } weak_alias (__tanh, tanh) #ifdef NO_LONG_DOUBLE diff --git a/sysdeps/ieee754/dbl-64/sincos32.c b/sysdeps/ieee754/dbl-64/sincos32.c index 954db66d6b..e42fd27250 100644 --- a/sysdeps/ieee754/dbl-64/sincos32.c +++ b/sysdeps/ieee754/dbl-64/sincos32.c @@ -43,317 +43,326 @@ #include "mpa.h" #include "sincos32.h" #include <math_private.h> +#include <stap-probe.h> #ifndef SECTION # define SECTION #endif -/****************************************************************/ -/* Compute Multi-Precision sin() function for given p. Receive */ -/* Multi Precision number x and result stored at y */ -/****************************************************************/ +/* Compute Multi-Precision sin() function for given p. Receive Multi Precision + number x and result stored at y. */ static void SECTION -ss32(mp_no *x, mp_no *y, int p) { +ss32 (mp_no *x, mp_no *y, int p) +{ int i; double a; - mp_no mpt1,x2,gor,sum ,mpk={1,{1.0}}; - for (i=1;i<=p;i++) mpk.d[i]=0; + mp_no mpt1, x2, gor, sum, mpk = {1, {1.0}}; + for (i = 1; i <= p; i++) + mpk.d[i] = 0; - __sqr(x,&x2,p); - __cpy(&oofac27,&gor,p); - __cpy(&gor,&sum,p); - for (a=27.0;a>1.0;a-=2.0) { - mpk.d[1]=a*(a-1.0); - __mul(&gor,&mpk,&mpt1,p); - __cpy(&mpt1,&gor,p); - __mul(&x2,&sum,&mpt1,p); - __sub(&gor,&mpt1,&sum,p); - } - __mul(x,&sum,y,p); + __sqr (x, &x2, p); + __cpy (&oofac27, &gor, p); + __cpy (&gor, &sum, p); + for (a = 27.0; a > 1.0; a -= 2.0) + { + mpk.d[1] = a * (a - 1.0); + __mul (&gor, &mpk, &mpt1, p); + __cpy (&mpt1, &gor, p); + __mul (&x2, &sum, &mpt1, p); + __sub (&gor, &mpt1, &sum, p); + } + __mul (x, &sum, y, p); } -/**********************************************************************/ -/* Compute Multi-Precision cos() function for given p. Receive Multi */ -/* Precision number x and result stored at y */ -/**********************************************************************/ +/* Compute Multi-Precision cos() function for given p. Receive Multi Precision + number x and result stored at y. */ static void SECTION -cc32(mp_no *x, mp_no *y, int p) { +cc32 (mp_no *x, mp_no *y, int p) +{ int i; double a; - mp_no mpt1,x2,gor,sum ,mpk={1,{1.0}}; - for (i=1;i<=p;i++) mpk.d[i]=0; + mp_no mpt1, x2, gor, sum, mpk = {1, {1.0}}; + for (i = 1; i <= p; i++) + mpk.d[i] = 0; - __sqr(x,&x2,p); - mpk.d[1]=27.0; - __mul(&oofac27,&mpk,&gor,p); - __cpy(&gor,&sum,p); - for (a=26.0;a>2.0;a-=2.0) { - mpk.d[1]=a*(a-1.0); - __mul(&gor,&mpk,&mpt1,p); - __cpy(&mpt1,&gor,p); - __mul(&x2,&sum,&mpt1,p); - __sub(&gor,&mpt1,&sum,p); - } - __mul(&x2,&sum,y,p); + __sqr (x, &x2, p); + mpk.d[1] = 27.0; + __mul (&oofac27, &mpk, &gor, p); + __cpy (&gor, &sum, p); + for (a = 26.0; a > 2.0; a -= 2.0) + { + mpk.d[1] = a * (a - 1.0); + __mul (&gor, &mpk, &mpt1, p); + __cpy (&mpt1, &gor, p); + __mul (&x2, &sum, &mpt1, p); + __sub (&gor, &mpt1, &sum, p); + } + __mul (&x2, &sum, y, p); } -/***************************************************************************/ -/* c32() computes both sin(x), cos(x) as Multi precision numbers */ -/***************************************************************************/ +/* Compute both sin(x), cos(x) as Multi precision numbers. */ void SECTION -__c32(mp_no *x, mp_no *y, mp_no *z, int p) { - mp_no u,t,t1,t2,c,s; +__c32 (mp_no *x, mp_no *y, mp_no *z, int p) +{ + mp_no u, t, t1, t2, c, s; int i; - __cpy(x,&u,p); - u.e=u.e-1; - cc32(&u,&c,p); - ss32(&u,&s,p); - for (i=0;i<24;i++) { - __mul(&c,&s,&t,p); - __sub(&s,&t,&t1,p); - __add(&t1,&t1,&s,p); - __sub(&mptwo,&c,&t1,p); - __mul(&t1,&c,&t2,p); - __add(&t2,&t2,&c,p); - } - __sub(&mpone,&c,y,p); - __cpy(&s,z,p); + __cpy (x, &u, p); + u.e = u.e - 1; + cc32 (&u, &c, p); + ss32 (&u, &s, p); + for (i = 0; i < 24; i++) + { + __mul (&c, &s, &t, p); + __sub (&s, &t, &t1, p); + __add (&t1, &t1, &s, p); + __sub (&mptwo, &c, &t1, p); + __mul (&t1, &c, &t2, p); + __add (&t2, &t2, &c, p); + } + __sub (&mpone, &c, y, p); + __cpy (&s, z, p); } -/************************************************************************/ -/*Routine receive double x and two double results of sin(x) and return */ -/*result which is more accurate */ -/*Computing sin(x) with multi precision routine c32 */ -/************************************************************************/ +/* Receive double x and two double results of sin(x) and return result which is + more accurate, computing sin(x) with multi precision routine c32. */ double SECTION -__sin32(double x, double res, double res1) { +__sin32 (double x, double res, double res1) +{ int p; - mp_no a,b,c; - p=32; - __dbl_mp(res,&a,p); - __dbl_mp(0.5*(res1-res),&b,p); - __add(&a,&b,&c,p); - if (x>0.8) - { __sub(&hp,&c,&a,p); - __c32(&a,&b,&c,p); - } - else __c32(&c,&a,&b,p); /* b=sin(0.5*(res+res1)) */ - __dbl_mp(x,&c,p); /* c = x */ - __sub(&b,&c,&a,p); - /* if a>0 return min(res,res1), otherwise return max(res,res1) */ - if (a.d[0]>0) return (res<res1)?res:res1; - else return (res>res1)?res:res1; + mp_no a, b, c; + p = 32; + __dbl_mp (res, &a, p); + __dbl_mp (0.5 * (res1 - res), &b, p); + __add (&a, &b, &c, p); + if (x > 0.8) + { + __sub (&hp, &c, &a, p); + __c32 (&a, &b, &c, p); + } + else + __c32 (&c, &a, &b, p); /* b=sin(0.5*(res+res1)) */ + __dbl_mp (x, &c, p); /* c = x */ + __sub (&b, &c, &a, p); + /* if a > 0 return min (res, res1), otherwise return max (res, res1). */ + if ((a.d[0] > 0 && res >= res1) || (a.d[0] <= 0 && res <= res1)) + res = res1; + LIBC_PROBE (slowasin, 2, &res, &x); + return res; } -/************************************************************************/ -/*Routine receive double x and two double results of cos(x) and return */ -/*result which is more accurate */ -/*Computing cos(x) with multi precision routine c32 */ -/************************************************************************/ +/* Receive double x and two double results of cos(x) and return result which is + more accurate, computing cos(x) with multi precision routine c32. */ double SECTION -__cos32(double x, double res, double res1) { +__cos32 (double x, double res, double res1) +{ int p; - mp_no a,b,c; - p=32; - __dbl_mp(res,&a,p); - __dbl_mp(0.5*(res1-res),&b,p); - __add(&a,&b,&c,p); - if (x>2.4) - { __sub(&pi,&c,&a,p); - __c32(&a,&b,&c,p); - b.d[0]=-b.d[0]; - } - else if (x>0.8) - { __sub(&hp,&c,&a,p); - __c32(&a,&c,&b,p); - } - else __c32(&c,&b,&a,p); /* b=cos(0.5*(res+res1)) */ - __dbl_mp(x,&c,p); /* c = x */ - __sub(&b,&c,&a,p); - /* if a>0 return max(res,res1), otherwise return min(res,res1) */ - if (a.d[0]>0) return (res>res1)?res:res1; - else return (res<res1)?res:res1; + mp_no a, b, c; + p = 32; + __dbl_mp (res, &a, p); + __dbl_mp (0.5 * (res1 - res), &b, p); + __add (&a, &b, &c, p); + if (x > 2.4) + { + __sub (&pi, &c, &a, p); + __c32 (&a, &b, &c, p); + b.d[0] = -b.d[0]; + } + else if (x > 0.8) + { + __sub (&hp, &c, &a, p); + __c32 (&a, &c, &b, p); + } + else + __c32 (&c, &b, &a, p); /* b=cos(0.5*(res+res1)) */ + __dbl_mp (x, &c, p); /* c = x */ + __sub (&b, &c, &a, p); + /* if a > 0 return max (res, res1), otherwise return min (res, res1). */ + if ((a.d[0] > 0 && res <= res1) || (a.d[0] <= 0 && res >= res1)) + res = res1; + LIBC_PROBE (slowacos, 2, &res, &x); + return res; } -/*******************************************************************/ -/*Compute sin(x+dx) as Multi Precision number and return result as */ -/* double */ -/*******************************************************************/ +/* Compute sin() of double-length number (X + DX) as Multi Precision number and + return result as double. If REDUCE_RANGE is true, X is assumed to be the + original input and DX is ignored. */ double SECTION -__mpsin(double x, double dx) { - int p; +__mpsin (double x, double dx, bool reduce_range) +{ double y; - mp_no a,b,c; - p=32; - __dbl_mp(x,&a,p); - __dbl_mp(dx,&b,p); - __add(&a,&b,&c,p); - if (x>0.8) { __sub(&hp,&c,&a,p); __c32(&a,&b,&c,p); } - else __c32(&c,&a,&b,p); /* b = sin(x+dx) */ - __mp_dbl(&b,&y,p); - return y; -} + mp_no a, b, c, s; + int n; + int p = 32; -/*******************************************************************/ -/* Compute cos()of double-length number (x+dx) as Multi Precision */ -/* number and return result as double */ -/*******************************************************************/ -double -SECTION -__mpcos(double x, double dx) { - int p; - double y; - mp_no a,b,c; - p=32; - __dbl_mp(x,&a,p); - __dbl_mp(dx,&b,p); - __add(&a,&b,&c,p); - if (x>0.8) - { __sub(&hp,&c,&b,p); - __c32(&b,&c,&a,p); - } - else __c32(&c,&a,&b,p); /* a = cos(x+dx) */ - __mp_dbl(&a,&y,p); - return y; -} + if (reduce_range) + { + n = __mpranred (x, &a, p); /* n is 0, 1, 2 or 3. */ + __c32 (&a, &c, &s, p); + } + else + { + n = -1; + __dbl_mp (x, &b, p); + __dbl_mp (dx, &c, p); + __add (&b, &c, &a, p); + if (x > 0.8) + { + __sub (&hp, &a, &b, p); + __c32 (&b, &s, &c, p); + } + else + __c32 (&a, &c, &s, p); /* b = sin(x+dx) */ + } -/******************************************************************/ -/* mpranred() performs range reduction of a double number x into */ -/* multi precision number y, such that y=x-n*pi/2, abs(y)<pi/4, */ -/* n=0,+-1,+-2,.... */ -/* Return int which indicates in which quarter of circle x is */ -/******************************************************************/ -int -SECTION -__mpranred(double x, mp_no *y, int p) -{ - number v; - double t,xn; - int i,k,n; - mp_no a,b,c; + /* Convert result based on which quarter of unit circle y is in. */ + switch (n) + { + case 1: + __mp_dbl (&c, &y, p); + break; + + case 3: + __mp_dbl (&c, &y, p); + y = -y; + break; + + case 2: + __mp_dbl (&s, &y, p); + y = -y; + break; - if (ABS(x) < 2.8e14) { - t = (x*hpinv.d + toint.d); - xn = t - toint.d; - v.d = t; - n =v.i[LOW_HALF]&3; - __dbl_mp(xn,&a,p); - __mul(&a,&hp,&b,p); - __dbl_mp(x,&c,p); - __sub(&c,&b,y,p); - return n; - } - else { /* if x is very big more precision required */ - __dbl_mp(x,&a,p); - a.d[0]=1.0; - k = a.e-5; - if (k < 0) k=0; - b.e = -k; - b.d[0] = 1.0; - for (i=0;i<p;i++) b.d[i+1] = toverp[i+k]; - __mul(&a,&b,&c,p); - t = c.d[c.e]; - for (i=1;i<=p-c.e;i++) c.d[i]=c.d[i+c.e]; - for (i=p+1-c.e;i<=p;i++) c.d[i]=0; - c.e=0; - if (c.d[1] >= HALFRAD) - { t +=1.0; - __sub(&c,&mpone,&b,p); - __mul(&b,&hp,y,p); + /* Quadrant not set, so the result must be sin (X + DX), which is also in + S. */ + case 0: + default: + __mp_dbl (&s, &y, p); } - else __mul(&c,&hp,y,p); - n = (int) t; - if (x < 0) { y->d[0] = - y->d[0]; n = -n; } - return (n&3); - } + LIBC_PROBE (slowsin, 3, &x, &dx, &y); + return y; } -/*******************************************************************/ -/* Multi-Precision sin() function subroutine, for p=32. It is */ -/* based on the routines mpranred() and c32(). */ -/*******************************************************************/ +/* Compute cos() of double-length number (X + DX) as Multi Precision number and + return result as double. If REDUCE_RANGE is true, X is assumed to be the + original input and DX is ignored. */ double SECTION -__mpsin1(double x) +__mpcos (double x, double dx, bool reduce_range) { - int p; - int n; - mp_no u,s,c; double y; - p=32; - n=__mpranred(x,&u,p); /* n is 0, 1, 2 or 3 */ - __c32(&u,&c,&s,p); - switch (n) { /* in which quarter of unit circle y is*/ - case 0: - __mp_dbl(&s,&y,p); - return y; - break; + mp_no a, b, c, s; + int n; + int p = 32; - case 2: - __mp_dbl(&s,&y,p); - return -y; - break; + if (reduce_range) + { + n = __mpranred (x, &a, p); /* n is 0, 1, 2 or 3. */ + __c32 (&a, &c, &s, p); + } + else + { + n = -1; + __dbl_mp (x, &b, p); + __dbl_mp (dx, &c, p); + __add (&b, &c, &a, p); + if (x > 0.8) + { + __sub (&hp, &a, &b, p); + __c32 (&b, &s, &c, p); + } + else + __c32 (&a, &c, &s, p); /* a = cos(x+dx) */ + } - case 1: - __mp_dbl(&c,&y,p); - return y; - break; + /* Convert result based on which quarter of unit circle y is in. */ + switch (n) + { + case 1: + __mp_dbl (&s, &y, p); + y = -y; + break; - case 3: - __mp_dbl(&c,&y,p); - return -y; - break; + case 3: + __mp_dbl (&s, &y, p); + break; - } - return 0; /* unreachable, to make the compiler happy */ -} + case 2: + __mp_dbl (&c, &y, p); + y = -y; + break; -/*****************************************************************/ -/* Multi-Precision cos() function subroutine, for p=32. It is */ -/* based on the routines mpranred() and c32(). */ -/*****************************************************************/ + /* Quadrant not set, so the result must be cos (X + DX), which is also + stored in C. */ + case 0: + default: + __mp_dbl (&c, &y, p); + } + LIBC_PROBE (slowcos, 3, &x, &dx, &y); + return y; +} -double +/* Perform range reduction of a double number x into multi precision number y, + such that y = x - n * pi / 2, abs (y) < pi / 4, n = 0, +-1, +-2, ... + Return int which indicates in which quarter of circle x is. */ +int SECTION -__mpcos1(double x) +__mpranred (double x, mp_no *y, int p) { - int p; - int n; - mp_no u,s,c; - double y; - - p=32; - n=__mpranred(x,&u,p); /* n is 0, 1, 2 or 3 */ - __c32(&u,&c,&s,p); - switch (n) { /* in what quarter of unit circle y is*/ - - case 0: - __mp_dbl(&c,&y,p); - return y; - break; - - case 2: - __mp_dbl(&c,&y,p); - return -y; - break; - - case 1: - __mp_dbl(&s,&y,p); - return -y; - break; - - case 3: - __mp_dbl(&s,&y,p); - return y; - break; + number v; + double t, xn; + int i, k, n; + mp_no a, b, c; - } - return 0; /* unreachable, to make the compiler happy */ + if (ABS (x) < 2.8e14) + { + t = (x * hpinv.d + toint.d); + xn = t - toint.d; + v.d = t; + n = v.i[LOW_HALF] & 3; + __dbl_mp (xn, &a, p); + __mul (&a, &hp, &b, p); + __dbl_mp (x, &c, p); + __sub (&c, &b, y, p); + return n; + } + else + { + /* If x is very big more precision required. */ + __dbl_mp (x, &a, p); + a.d[0] = 1.0; + k = a.e - 5; + if (k < 0) + k = 0; + b.e = -k; + b.d[0] = 1.0; + for (i = 0; i < p; i++) + b.d[i + 1] = toverp[i + k]; + __mul (&a, &b, &c, p); + t = c.d[c.e]; + for (i = 1; i <= p - c.e; i++) + c.d[i] = c.d[i + c.e]; + for (i = p + 1 - c.e; i <= p; i++) + c.d[i] = 0; + c.e = 0; + if (c.d[1] >= HALFRAD) + { + t += 1.0; + __sub (&c, &mpone, &b, p); + __mul (&b, &hp, y, p); + } + else + __mul (&c, &hp, y, p); + n = (int) t; + if (x < 0) + { + y->d[0] = -y->d[0]; + n = -n; + } + return (n & 3); + } } -/******************************************************************/ diff --git a/sysdeps/ieee754/dbl-64/slowexp.c b/sysdeps/ieee754/dbl-64/slowexp.c index 8f353f634f..525224f44a 100644 --- a/sysdeps/ieee754/dbl-64/slowexp.c +++ b/sysdeps/ieee754/dbl-64/slowexp.c @@ -29,6 +29,8 @@ /**************************************************************************/ #include <math_private.h> +#include <stap-probe.h> + #ifndef USE_LONG_DOUBLE_FOR_MP # include "mpa.h" void __mpexp (mp_no *x, mp_no *y, int p); @@ -60,13 +62,22 @@ __slowexp (double x) __mp_dbl (&mpw, &w, p); __mp_dbl (&mpz, &z, p); if (w == z) - return w; + { + /* Track how often we get to the slow exp code plus + its input/output values. */ + LIBC_PROBE (slowexp_p6, 2, &x, &w); + return w; + } else { p = 32; __dbl_mp (x, &mpx, p); __mpexp (&mpx, &mpy, p); __mp_dbl (&mpy, &res, p); + + /* Track how often we get to the uber-slow exp code plus + its input/output values. */ + LIBC_PROBE (slowexp_p32, 2, &x, &res); return res; } #else diff --git a/sysdeps/ieee754/dbl-64/slowpow.c b/sysdeps/ieee754/dbl-64/slowpow.c index a379728b14..d200c39e59 100644 --- a/sysdeps/ieee754/dbl-64/slowpow.c +++ b/sysdeps/ieee754/dbl-64/slowpow.c @@ -34,6 +34,8 @@ #include "mpa.h" #include <math_private.h> +#include <stap-probe.h> + #ifndef SECTION # define SECTION #endif @@ -97,7 +99,12 @@ __slowpow (double x, double y, double z) __sub (&mpp, &eps, &mpr1, p); __mp_dbl (&mpr1, &res1, p); if (res == res1) - return res; + { + /* Track how often we get to the slow pow code plus + its input/output values. */ + LIBC_PROBE (slowpow_p10, 4, &x, &y, &z, &res); + return res; + } /* If we don't, then we repeat using a higher precision. 768 bits of precision ought to be enough for anybody. */ @@ -109,5 +116,10 @@ __slowpow (double x, double y, double z) __mul (&mpy, &mpz, &mpw, p); __mpexp (&mpw, &mpp, p); __mp_dbl (&mpp, &res, p); + + /* Track how often we get to the uber-slow pow code plus + its input/output values. */ + LIBC_PROBE (slowpow_p32, 4, &x, &y, &z, &res); + return res; } diff --git a/sysdeps/ieee754/dbl-64/usncs.h b/sysdeps/ieee754/dbl-64/usncs.h index 11c189ce34..209c74f33d 100644 --- a/sysdeps/ieee754/dbl-64/usncs.h +++ b/sysdeps/ieee754/dbl-64/usncs.h @@ -27,51 +27,22 @@ #ifndef USNCS_H #define USNCS_H -#ifdef BIG_ENDI -static const mynumber - -/**/ s1 = {{0xBFC55555, 0x55555555 }}, /* -0.16666666666666666 */ -/**/ s2 = {{0x3F811111, 0x11110ECE }}, /* 0.0083333333333323288 */ -/**/ s3 = {{0xBF2A01A0, 0x19DB08B8 }}, /* -0.00019841269834414642 */ -/**/ s4 = {{0x3EC71DE2, 0x7B9A7ED9 }}, /* 2.755729806860771e-06 */ -/**/ s5 = {{0xBE5ADDFF, 0xC2FCDF59 }}, /* -2.5022014848318398e-08 */ -/**/ aa = {{0xBFC55580, 0x00000000 }}, /* -0.1666717529296875 */ -/**/ bb = {{0x3ED55555, 0x55556E24 }}, /* 5.0862630208387126e-06 */ -/**/ big = {{0x42c80000, 0x00000000 }}, /* 52776558133248 */ -/**/ hp0 = {{0x3FF921FB, 0x54442D18 }}, /* 1.5707963267948966 */ -/**/ hp1 = {{0x3C91A626, 0x33145C07 }}, /* 6.123233995736766e-17 */ -/**/ mp1 = {{0x3FF921FB, 0x58000000 }}, /* 1.5707963407039642 */ -/**/ mp2 = {{0xBE4DDE97, 0x3C000000 }}, /* -1.3909067564377153e-08 */ -/**/ mp3 = {{0xBC8CB3B3, 0x99D747F2 }}, /* -4.9789962505147994e-17 */ -/**/ pp3 = {{0xBC8CB3B3, 0x98000000 }}, /* -4.9789962314799099e-17 */ -/**/ pp4 = {{0xbacd747f, 0x23e32ed7 }}, /* -1.9034889620193266e-25 */ -/**/ hpinv = {{0x3FE45F30, 0x6DC9C883 }}, /* 0.63661977236758138 */ -/**/ toint = {{0x43380000, 0x00000000 }}; /* 6755399441055744 */ - -#else -#ifdef LITTLE_ENDI -static const mynumber - -/**/ s1 = {{0x55555555, 0xBFC55555 }},/* -0.16666666666666666 */ -/**/ s2 = {{0x11110ECE, 0x3F811111 }},/* 0.0083333333333323288 */ -/**/ s3 = {{0x19DB08B8, 0xBF2A01A0 }},/* -0.00019841269834414642 */ -/**/ s4 = {{0x7B9A7ED9, 0x3EC71DE2 }},/* 2.755729806860771e-06 */ -/**/ s5 = {{0xC2FCDF59, 0xBE5ADDFF }},/* -2.5022014848318398e-08 */ -/**/ aa = {{0x00000000, 0xBFC55580 }},/* -0.1666717529296875 */ -/**/ bb = {{0x55556E24, 0x3ED55555 }},/* 5.0862630208387126e-06 */ -/**/ big = {{0x00000000, 0x42c80000 }},/* 52776558133248 */ -/**/ hp0 = {{0x54442D18, 0x3FF921FB }},/* 1.5707963267948966 */ -/**/ hp1 = {{0x33145C07, 0x3C91A626 }},/* 6.123233995736766e-17 */ -/**/ mp1 = {{0x58000000, 0x3FF921FB }},/* 1.5707963407039642 */ -/**/ mp2 = {{0x3C000000, 0xBE4DDE97 }},/* -1.3909067564377153e-08 */ -/**/ mp3 = {{0x99D747F2, 0xBC8CB3B3 }},/* -4.9789962505147994e-17 */ -/**/ pp3 = {{0x98000000, 0xBC8CB3B3 }},/* -4.9789962314799099e-17 */ -/**/ pp4 = {{0x23e32ed7, 0xbacd747f }},/* -1.9034889620193266e-25 */ -/**/ hpinv = {{0x6DC9C883, 0x3FE45F30 }},/* 0.63661977236758138 */ -/**/ toint = {{0x00000000, 0x43380000 }};/* 6755399441055744 */ - - -#endif -#endif +static const double s1 = -0x1.5555555555555p-3; /* -0.16666666666666666 */ +static const double s2 = 0x1.1111111110ECEp-7; /* 0.0083333333333323288 */ +static const double s3 = -0x1.A01A019DB08B8p-13; /* -0.00019841269834414642 */ +static const double s4 = 0x1.71DE27B9A7ED9p-19; /* 2.755729806860771e-06 */ +static const double s5 = -0x1.ADDFFC2FCDF59p-26; /* -2.5022014848318398e-08 */ +static const double aa = -0x1.5558000000000p-3; /* -0.1666717529296875 */ +static const double bb = 0x1.5555555556E24p-18; /* 5.0862630208387126e-06 */ +static const double big = 0x1.8000000000000p45; /* 52776558133248 */ +static const double hp0 = 0x1.921FB54442D18p0; /* 1.5707963267948966 */ +static const double hp1 = 0x1.1A62633145C07p-54; /* 6.123233995736766e-17 */ +static const double mp1 = 0x1.921FB58000000p0; /* 1.5707963407039642 */ +static const double mp2 = -0x1.DDE973C000000p-27; /* -1.3909067564377153e-08 */ +static const double mp3 = -0x1.CB3B399D747F2p-55; /* -4.9789962505147994e-17 */ +static const double pp3 = -0x1.CB3B398000000p-55; /* -4.9789962314799099e-17 */ +static const double pp4 = -0x1.d747f23e32ed7p-83; /* -1.9034889620193266e-25 */ +static const double hpinv = 0x1.45F306DC9C883p-1; /* 0.63661977236758138 */ +static const double toint = 0x1.8000000000000p52; /* 6755399441055744 */ #endif diff --git a/sysdeps/ieee754/flt-32/e_jnf.c b/sysdeps/ieee754/flt-32/e_jnf.c index ad26d7e8a6..5984d94a3c 100644 --- a/sysdeps/ieee754/flt-32/e_jnf.c +++ b/sysdeps/ieee754/flt-32/e_jnf.c @@ -54,7 +54,7 @@ __ieee754_jnf(int n, float x) b = __ieee754_j1f(x); for(i=1;i<n;i++){ temp = b; - b = b*((float)(i+i)/x) - a; /* avoid underflow */ + b = b*((double)(i+i)/x) - a; /* avoid underflow */ a = temp; } } else { @@ -196,7 +196,7 @@ __ieee754_ynf(int n, float x) GET_FLOAT_WORD(ib,b); for(i=1;i<n&&ib!=0xff800000;i++){ temp = b; - b = ((float)(i+i)/x)*b - a; + b = ((double)(i+i)/x)*b - a; GET_FLOAT_WORD(ib,b); a = temp; } diff --git a/sysdeps/ieee754/flt-32/e_lgammaf_r.c b/sysdeps/ieee754/flt-32/e_lgammaf_r.c index 2e92269085..0dba9af8d7 100644 --- a/sysdeps/ieee754/flt-32/e_lgammaf_r.c +++ b/sysdeps/ieee754/flt-32/e_lgammaf_r.c @@ -150,8 +150,8 @@ __ieee754_lgammaf_r(float x, int *signgamp) *signgamp = -1; return one/fabsf(x); } - if(__builtin_expect(ix<0x1c800000, 0)) { - /* |x|<2**-70, return -log(|x|) */ + if(__builtin_expect(ix<0x30800000, 0)) { + /* |x|<2**-30, return -log(|x|) */ if(hx<0) { *signgamp = -1; return -__ieee754_logf(-x); diff --git a/sysdeps/ieee754/flt-32/s_erff.c b/sysdeps/ieee754/flt-32/s_erff.c index 7d17f426e9..7c09589648 100644 --- a/sysdeps/ieee754/flt-32/s_erff.c +++ b/sysdeps/ieee754/flt-32/s_erff.c @@ -17,6 +17,8 @@ static char rcsid[] = "$NetBSD: s_erff.c,v 1.4 1995/05/10 20:47:07 jtc Exp $"; #endif +#include <errno.h> +#include <float.h> #include <math.h> #include <math_private.h> @@ -203,9 +205,22 @@ float __erfcf(float x) SET_FLOAT_WORD(z,ix&0xffffe000); r = __ieee754_expf(-z*z-(float)0.5625)* __ieee754_expf((z-x)*(z+x)+R/S); - if(hx>0) return r/x; else return two-r/x; + if(hx>0) { +#if FLT_EVAL_METHOD != 0 + volatile +#endif + float ret = r/x; + if (ret == 0) + __set_errno (ERANGE); + return ret; + } else + return two-r/x; } else { - if(hx>0) return tiny*tiny; else return two-tiny; + if(hx>0) { + __set_errno (ERANGE); + return tiny*tiny; + } else + return two-tiny; } } weak_alias (__erfcf, erfcf) diff --git a/sysdeps/ieee754/flt-32/s_finitef.c b/sysdeps/ieee754/flt-32/s_finitef.c index dfdf4ad0b7..4ea270ae07 100644 --- a/sysdeps/ieee754/flt-32/s_finitef.c +++ b/sysdeps/ieee754/flt-32/s_finitef.c @@ -26,7 +26,12 @@ static char rcsid[] = "$NetBSD: s_finitef.c,v 1.4 1995/05/10 20:47:18 jtc Exp $" #include <math_private.h> #undef __finitef -int __finitef(float x) + +#ifndef FINITEF +# define FINITEF __finitef +#endif + +int FINITEF(float x) { int32_t ix; GET_FLOAT_WORD(ix,x); diff --git a/sysdeps/ieee754/k_standard.c b/sysdeps/ieee754/k_standard.c index 4a0d82d1a6..5399c6682d 100644 --- a/sysdeps/ieee754/k_standard.c +++ b/sysdeps/ieee754/k_standard.c @@ -248,7 +248,7 @@ __kernel_standard(double x, double y, int type) else exc.retval = -HUGE_VAL; if (_LIB_VERSION == _POSIX_) - __set_errno (EDOM); + __set_errno (ERANGE); else if (!matherr(&exc)) { if (_LIB_VERSION == _SVID_) { (void) WRITE2("y0: DOMAIN error\n", 17); @@ -265,7 +265,7 @@ __kernel_standard(double x, double y, int type) if (_LIB_VERSION == _SVID_) exc.retval = -HUGE; else - exc.retval = -HUGE_VAL; + exc.retval = NAN; if (_LIB_VERSION == _POSIX_) __set_errno (EDOM); else if (!matherr(&exc)) { @@ -286,7 +286,7 @@ __kernel_standard(double x, double y, int type) else exc.retval = -HUGE_VAL; if (_LIB_VERSION == _POSIX_) - __set_errno (EDOM); + __set_errno (ERANGE); else if (!matherr(&exc)) { if (_LIB_VERSION == _SVID_) { (void) WRITE2("y1: DOMAIN error\n", 17); @@ -303,7 +303,7 @@ __kernel_standard(double x, double y, int type) if (_LIB_VERSION == _SVID_) exc.retval = -HUGE; else - exc.retval = -HUGE_VAL; + exc.retval = NAN; if (_LIB_VERSION == _POSIX_) __set_errno (EDOM); else if (!matherr(&exc)) { @@ -322,9 +322,11 @@ __kernel_standard(double x, double y, int type) if (_LIB_VERSION == _SVID_) exc.retval = -HUGE; else - exc.retval = -HUGE_VAL; + exc.retval = ((x < 0 && ((int) x & 1) != 0) + ? HUGE_VAL + : -HUGE_VAL); if (_LIB_VERSION == _POSIX_) - __set_errno (EDOM); + __set_errno (ERANGE); else if (!matherr(&exc)) { if (_LIB_VERSION == _SVID_) { (void) WRITE2("yn: DOMAIN error\n", 17); @@ -341,7 +343,7 @@ __kernel_standard(double x, double y, int type) if (_LIB_VERSION == _SVID_) exc.retval = -HUGE; else - exc.retval = -HUGE_VAL; + exc.retval = NAN; if (_LIB_VERSION == _POSIX_) __set_errno (EDOM); else if (!matherr(&exc)) { diff --git a/sysdeps/ieee754/ldbl-128/e_hypotl.c b/sysdeps/ieee754/ldbl-128/e_hypotl.c index f5ab901e6a..01444cfb4e 100644 --- a/sysdeps/ieee754/ldbl-128/e_hypotl.c +++ b/sysdeps/ieee754/ldbl-128/e_hypotl.c @@ -89,6 +89,17 @@ __ieee754_hypotl(long double x, long double y) b *= t1; a *= t1; k -= 16382; + GET_LDOUBLE_MSW64 (ha, a); + GET_LDOUBLE_MSW64 (hb, b); + if (hb > ha) + { + t1 = a; + a = b; + b = t1; + j = ha; + ha = hb; + hb = j; + } } else { /* scale a and b by 2^9600 */ ha += 0x2580000000000000LL; /* a *= 2^9600 */ hb += 0x2580000000000000LL; /* b *= 2^9600 */ diff --git a/sysdeps/ieee754/ldbl-128/e_jnl.c b/sysdeps/ieee754/ldbl-128/e_jnl.c index 70d5672fd9..c2a49235c3 100644 --- a/sysdeps/ieee754/ldbl-128/e_jnl.c +++ b/sysdeps/ieee754/ldbl-128/e_jnl.c @@ -316,7 +316,7 @@ __ieee754_ynl (int n, long double x) if (x <= 0.0L) { if (x == 0.0L) - return -HUGE_VALL + x; + return ((n < 0 && (n & 1) != 0) ? 1.0L : -1.0L) / 0.0L; if (se & 0x80000000) return zero / (zero * x); } diff --git a/sysdeps/ieee754/ldbl-128/e_logl.c b/sysdeps/ieee754/ldbl-128/e_logl.c index 395a76302a..3d1034dd61 100644 --- a/sysdeps/ieee754/ldbl-128/e_logl.c +++ b/sysdeps/ieee754/ldbl-128/e_logl.c @@ -212,9 +212,8 @@ __ieee754_logl(long double x) } /* Extract exponent and reduce domain to 0.703125 <= u < 1.40625 */ - e = (int) (m >> 16) - (int) 0x3ffe; - m &= 0xffff; - u.parts32.w0 = m | 0x3ffe0000; + u.value = __frexpl (x, &e); + m = u.parts32.w0 & 0xffff; m |= 0x10000; /* Find lookup table index k from high order bits of the significand. */ if (m < 0x16800) diff --git a/sysdeps/ieee754/ldbl-128/printf_fphex.c b/sysdeps/ieee754/ldbl-128/printf_fphex.c index c9e09a4b74..e82228a53e 100644 --- a/sysdeps/ieee754/ldbl-128/printf_fphex.c +++ b/sysdeps/ieee754/ldbl-128/printf_fphex.c @@ -24,13 +24,15 @@ do { \ digits we use only the implicit digits for the number before \ the decimal point. */ \ unsigned long long int num0, num1; \ + union ieee854_long_double u; \ + u.d = fpnum.ldbl; \ \ assert (sizeof (long double) == 16); \ \ - num0 = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \ - | fpnum.ldbl.ieee.mantissa1); \ - num1 = (((unsigned long long int) fpnum.ldbl.ieee.mantissa2) << 32 \ - | fpnum.ldbl.ieee.mantissa3); \ + num0 = (((unsigned long long int) u.ieee.mantissa0) << 32 \ + | u.ieee.mantissa1); \ + num1 = (((unsigned long long int) u.ieee.mantissa2) << 32 \ + | u.ieee.mantissa3); \ \ zero_mantissa = (num0|num1) == 0; \ \ @@ -75,9 +77,9 @@ do { \ *--wnumstr = L'0'; \ } \ \ - leading = fpnum.ldbl.ieee.exponent == 0 ? '0' : '1'; \ + leading = u.ieee.exponent == 0 ? '0' : '1'; \ \ - exponent = fpnum.ldbl.ieee.exponent; \ + exponent = u.ieee.exponent; \ \ if (exponent == 0) \ { \ diff --git a/sysdeps/ieee754/ldbl-128/s_erfl.c b/sysdeps/ieee754/ldbl-128/s_erfl.c index d9d4195ad2..ef65ed8922 100644 --- a/sysdeps/ieee754/ldbl-128/s_erfl.c +++ b/sysdeps/ieee754/ldbl-128/s_erfl.c @@ -96,6 +96,7 @@ * erfc/erf(NaN) is NaN */ +#include <errno.h> #include <math.h> #include <math_private.h> @@ -918,14 +919,22 @@ __erfcl (long double x) r = __ieee754_expl (-z * z - 0.5625) * __ieee754_expl ((z - x) * (z + x) + p); if ((sign & 0x80000000) == 0) - return r / x; + { + long double ret = r / x; + if (ret == 0) + __set_errno (ERANGE); + return ret; + } else return two - r / x; } else { if ((sign & 0x80000000) == 0) - return tiny * tiny; + { + __set_errno (ERANGE); + return tiny * tiny; + } else return two - tiny; } diff --git a/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c b/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c index abc78a35bd..8a4a5bb7b9 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c @@ -36,8 +36,12 @@ __ieee754_acoshl(long double x) { long double t; int64_t hx; - u_int64_t lx; - GET_LDOUBLE_WORDS64(hx,lx,x); + uint64_t lx; + double xhi, xlo; + + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS64 (hx, xhi); + EXTRACT_WORDS64 (lx, xlo); if(hx<0x3ff0000000000000LL) { /* x < 1 */ return (x-x)/(x-x); } else if(hx >=0x41b0000000000000LL) { /* x > 2**28 */ diff --git a/sysdeps/ieee754/ldbl-128ibm/e_acosl.c b/sysdeps/ieee754/ldbl-128ibm/e_acosl.c index 5d2af30346..2cb288238b 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_acosl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_acosl.c @@ -151,26 +151,27 @@ static const long double long double __ieee754_acosl (long double x) { - long double z, r, w, p, q, s, t, f2; - ieee854_long_double_shape_type u; + long double a, z, r, w, p, q, s, t, f2; - u.value = __builtin_fabsl (x); - if (u.value == 1.0L) + if (__glibc_unlikely (__isnanl (x))) + return x + x; + a = __builtin_fabsl (x); + if (a == 1.0L) { if (x > 0.0L) return 0.0; /* acos(1) = 0 */ else return (2.0 * pio2_hi) + (2.0 * pio2_lo); /* acos(-1)= pi */ } - else if (u.value > 1.0L) + else if (a > 1.0L) { return (x - x) / (x - x); /* acos(|x| > 1) is NaN */ } - if (u.value < 0.5L) + if (a < 0.5L) { - if (u.value < 6.938893903907228e-18L) /* |x| < 2**-57 */ + if (a < 6.938893903907228e-18L) /* |x| < 2**-57 */ return pio2_hi + pio2_lo; - if (u.value < 0.4375L) + if (a < 0.4375L) { /* Arcsine of x. */ z = x * x; @@ -199,7 +200,7 @@ __ieee754_acosl (long double x) return z; } /* .4375 <= |x| < .5 */ - t = u.value - 0.4375L; + t = a - 0.4375L; p = ((((((((((P10 * t + P9) * t + P8) * t @@ -230,9 +231,9 @@ __ieee754_acosl (long double x) r = acosr4375 + r; return r; } - else if (u.value < 0.625L) + else if (a < 0.625L) { - t = u.value - 0.5625L; + t = a - 0.5625L; p = ((((((((((rS10 * t + rS9) * t + rS8) * t @@ -264,7 +265,9 @@ __ieee754_acosl (long double x) } else { /* |x| >= .625 */ - z = (one - u.value) * 0.5; + double shi, slo; + + z = (one - a) * 0.5; s = __ieee754_sqrtl (z); /* Compute an extended precision square root from the Newton iteration s -> 0.5 * (s + z / s). @@ -273,12 +276,11 @@ __ieee754_acosl (long double x) Express s = f1 + f2 where f1 * f1 is exactly representable. w = (z - s^2)/2s = (z - f1^2 - 2 f1 f2 - f2^2)/2s . s + w has extended precision. */ - u.value = s; - u.parts32.w2 = 0; - u.parts32.w3 = 0; - f2 = s - u.value; - w = z - u.value * u.value; - w = w - 2.0 * u.value * f2; + ldbl_unpack (s, &shi, &slo); + a = shi; + f2 = slo; + w = z - a * a; + w = w - 2.0 * a * f2; w = w - f2 * f2; w = w / (2.0 * s); /* Arcsine of s. */ diff --git a/sysdeps/ieee754/ldbl-128ibm/e_asinl.c b/sysdeps/ieee754/ldbl-128ibm/e_asinl.c index b395439495..dece11875b 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_asinl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_asinl.c @@ -131,19 +131,20 @@ static const long double long double __ieee754_asinl (long double x) { - long double t, w, p, q, c, r, s; + long double a, t, w, p, q, c, r, s; int flag; - ieee854_long_double_shape_type u; + if (__glibc_unlikely (__isnanl (x))) + return x + x; flag = 0; - u.value = __builtin_fabsl (x); - if (u.value == 1.0L) /* |x|>= 1 */ + a = __builtin_fabsl (x); + if (a == 1.0L) /* |x|>= 1 */ return x * pio2_hi + x * pio2_lo; /* asin(1)=+-pi/2 with inexact */ - else if (u.value >= 1.0L) + else if (a >= 1.0L) return (x - x) / (x - x); /* asin(|x|>1) is NaN */ - else if (u.value < 0.5L) + else if (a < 0.5L) { - if (u.value < 6.938893903907228e-18L) /* |x| < 2**-57 */ + if (a < 6.938893903907228e-18L) /* |x| < 2**-57 */ { if (huge + x > one) return x; /* return x with inexact if x!=0 */ @@ -155,9 +156,9 @@ __ieee754_asinl (long double x) flag = 1; } } - else if (u.value < 0.625L) + else if (a < 0.625L) { - t = u.value - 0.5625; + t = a - 0.5625; p = ((((((((((rS10 * t + rS9) * t + rS8) * t @@ -190,7 +191,7 @@ __ieee754_asinl (long double x) else { /* 1 > |x| >= 0.625 */ - w = one - u.value; + w = one - a; t = w * 0.5; } @@ -223,17 +224,14 @@ __ieee754_asinl (long double x) } s = __ieee754_sqrtl (t); - if (u.value > 0.975L) + if (a > 0.975L) { w = p / q; t = pio2_hi - (2.0 * (s + s * w) - pio2_lo); } else { - u.value = s; - u.parts32.w3 = 0; - u.parts32.w2 = 0; - w = u.value; + w = ldbl_high (s); c = (t - w * w) / (s + w); r = p / q; p = 2.0 * s * r - (pio2_lo - 2.0 * c); diff --git a/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c b/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c index 3e0535561c..b625323df3 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c @@ -56,11 +56,15 @@ __ieee754_atan2l(long double y, long double x) { long double z; int64_t k,m,hx,hy,ix,iy; - u_int64_t lx,ly; + uint64_t lx; + double xhi, xlo, yhi; - GET_LDOUBLE_WORDS64(hx,lx,x); + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS64 (hx, xhi); + EXTRACT_WORDS64 (lx, xlo); ix = hx&0x7fffffffffffffffLL; - GET_LDOUBLE_WORDS64(hy,ly,y); + yhi = ldbl_high (y); + EXTRACT_WORDS64 (hy, yhi); iy = hy&0x7fffffffffffffffLL; if(((ix)>0x7ff0000000000000LL)|| ((iy)>0x7ff0000000000000LL)) /* x or y is NaN */ @@ -70,7 +74,7 @@ __ieee754_atan2l(long double y, long double x) m = ((hy>>63)&1)|((hx>>62)&2); /* 2*sign(x)+sign(y) */ /* when y = 0 */ - if((iy|(ly&0x7fffffffffffffffLL))==0) { + if(iy==0) { switch(m) { case 0: case 1: return y; /* atan(+-0,+anything)=+-0 */ @@ -79,7 +83,7 @@ __ieee754_atan2l(long double y, long double x) } } /* when x = 0 */ - if((ix|(lx&0x7fffffffffffffff))==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + if(ix==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; /* when x is INF */ if(ix==0x7ff0000000000000LL) { diff --git a/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c b/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c index f35182f03e..29f2e92072 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c @@ -40,8 +40,10 @@ __ieee754_atanhl(long double x) { long double t; int64_t hx,ix; - u_int64_t lx __attribute__ ((unused)); - GET_LDOUBLE_WORDS64(hx,lx,x); + double xhi; + + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); ix = hx&0x7fffffffffffffffLL; if (ix >= 0x3ff0000000000000LL) { /* |x|>=1 */ if (ix > 0x3ff0000000000000LL) diff --git a/sysdeps/ieee754/ldbl-128ibm/e_coshl.c b/sysdeps/ieee754/ldbl-128ibm/e_coshl.c index 3e8e1875c6..05683bc02f 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_coshl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_coshl.c @@ -41,9 +41,11 @@ __ieee754_coshl (long double x) { long double t,w; int64_t ix; + double xhi; /* High word of |x|. */ - GET_LDOUBLE_MSW64(ix,x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (ix, xhi); ix &= 0x7fffffffffffffffLL; /* x is INF or NaN */ diff --git a/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c b/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c index 1eaf2fe398..49121ca315 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c @@ -36,9 +36,9 @@ __ieee754_exp10l (long double arg) else if (arg > LDBL_MAX_10_EXP + 1) return LDBL_MAX * LDBL_MAX; - u.d = arg; - arg_high = u.dd[0]; - arg_low = u.dd[1]; + u.ld = arg; + arg_high = u.d[0].d; + arg_low = u.d[1].d; exp_high = arg_high * log10_high; exp_low = arg_high * log10_low + arg_low * M_LN10l; return __ieee754_expl (exp_high) * __ieee754_expl (exp_low); diff --git a/sysdeps/ieee754/ldbl-128ibm/e_expl.c b/sysdeps/ieee754/ldbl-128ibm/e_expl.c index 1b994cd7a9..65ef18532d 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_expl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_expl.c @@ -134,18 +134,17 @@ static const long double C[] = { long double __ieee754_expl (long double x) { + long double result, x22; + union ibm_extended_long_double ex2_u, scale_u; + int unsafe; + /* Check for usual case. */ if (isless (x, himark) && isgreater (x, lomark)) { - int tval1, tval2, unsafe, n_i, exponent2; - long double x22, n, result, xl; - union ibm_extended_long_double ex2_u, scale_u; - fenv_t oldenv; - - feholdexcept (&oldenv); -#ifdef FE_TONEAREST - fesetround (FE_TONEAREST); -#endif + int tval1, tval2, n_i, exponent2; + long double n, xl; + + SET_RESTORE_ROUND (FE_TONEAREST); n = __roundl (x*M_1_LN2); x = x-n*M_LN2_0; @@ -162,50 +161,45 @@ __ieee754_expl (long double x) x = x + xl; /* Compute ex2 = 2^n_0 e^(argtable[tval1]) e^(argtable[tval2]). */ - ex2_u.d = __expl_table[T_EXPL_RES1 + tval1] - * __expl_table[T_EXPL_RES2 + tval2]; + ex2_u.ld = (__expl_table[T_EXPL_RES1 + tval1] + * __expl_table[T_EXPL_RES2 + tval2]); n_i = (int)n; /* 'unsafe' is 1 iff n_1 != 0. */ unsafe = fabsl(n_i) >= -LDBL_MIN_EXP - 1; - ex2_u.ieee.exponent += n_i >> unsafe; + ex2_u.d[0].ieee.exponent += n_i >> unsafe; /* Fortunately, there are no subnormal lowpart doubles in __expl_table, only normal values and zeros. But after scaling it can be subnormal. */ - exponent2 = ex2_u.ieee.exponent2 + (n_i >> unsafe); - if (ex2_u.ieee.exponent2 == 0) - /* assert ((ex2_u.ieee.mantissa2|ex2_u.ieee.mantissa3) == 0) */; + exponent2 = ex2_u.d[1].ieee.exponent + (n_i >> unsafe); + if (ex2_u.d[1].ieee.exponent == 0) + /* assert ((ex2_u.d[1].ieee.mantissa0|ex2_u.d[1].ieee.mantissa1) == 0) */; else if (exponent2 > 0) - ex2_u.ieee.exponent2 = exponent2; + ex2_u.d[1].ieee.exponent = exponent2; else if (exponent2 <= -54) { - ex2_u.ieee.exponent2 = 0; - ex2_u.ieee.mantissa2 = 0; - ex2_u.ieee.mantissa3 = 0; + ex2_u.d[1].ieee.exponent = 0; + ex2_u.d[1].ieee.mantissa0 = 0; + ex2_u.d[1].ieee.mantissa1 = 0; } else { static const double two54 = 1.80143985094819840000e+16, /* 4350000000000000 */ twom54 = 5.55111512312578270212e-17; /* 3C90000000000000 */ - ex2_u.dd[1] *= two54; - ex2_u.ieee.exponent2 += n_i >> unsafe; - ex2_u.dd[1] *= twom54; + ex2_u.d[1].d *= two54; + ex2_u.d[1].ieee.exponent += n_i >> unsafe; + ex2_u.d[1].d *= twom54; } /* Compute scale = 2^n_1. */ - scale_u.d = 1.0L; - scale_u.ieee.exponent += n_i - (n_i >> unsafe); + scale_u.ld = 1.0L; + scale_u.d[0].ieee.exponent += n_i - (n_i >> unsafe); /* Approximate e^x2 - 1, using a seventh-degree polynomial, with maximum error in [-2^-16-2^-53,2^-16+2^-53] less than 4.8e-39. */ x22 = x + x*x*(P1+x*(P2+x*(P3+x*(P4+x*(P5+x*P6))))); - /* Return result. */ - fesetenv (&oldenv); - - result = x22 * ex2_u.d + ex2_u.d; - /* Now we can test whether the result is ultimate or if we are unsure. In the later case we should probably call a mpn based routine to give the ultimate result. @@ -235,10 +229,6 @@ __ieee754_expl (long double x) return __ieee754_expl_proc2 (origx); } */ - if (!unsafe) - return result; - else - return result * scale_u.d; } /* Exceptional cases: */ else if (isless (x, himark)) @@ -253,5 +243,10 @@ __ieee754_expl (long double x) else /* Return x, if x is a NaN or Inf; or overflow, otherwise. */ return TWO1023*x; + + result = x22 * ex2_u.ld + ex2_u.ld; + if (!unsafe) + return result; + return result * scale_u.ld; } strong_alias (__ieee754_expl, __expl_finite) diff --git a/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c b/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c index a60963c84d..a140fb322d 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c @@ -27,76 +27,83 @@ static const long double one = 1.0, Zero[] = {0.0, -0.0,}; long double __ieee754_fmodl (long double x, long double y) { - int64_t n,hx,hy,hz,ix,iy,sx, i; - u_int64_t lx,ly,lz; - int temp; + int64_t hx, hy, hz, sx, sy; + uint64_t lx, ly, lz; + int n, ix, iy; + double xhi, xlo, yhi, ylo; - GET_LDOUBLE_WORDS64(hx,lx,x); - GET_LDOUBLE_WORDS64(hy,ly,y); + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS64 (hx, xhi); + EXTRACT_WORDS64 (lx, xlo); + ldbl_unpack (y, &yhi, &ylo); + EXTRACT_WORDS64 (hy, yhi); + EXTRACT_WORDS64 (ly, ylo); sx = hx&0x8000000000000000ULL; /* sign of x */ - hx ^=sx; /* |x| */ - hy &= 0x7fffffffffffffffLL; /* |y| */ + hx ^= sx; /* |x| */ + sy = hy&0x8000000000000000ULL; /* sign of y */ + hy ^= sy; /* |y| */ /* purge off exception values */ - if(__builtin_expect((hy|(ly&0x7fffffffffffffff))==0 || + if(__builtin_expect(hy==0 || (hx>=0x7ff0000000000000LL)|| /* y=0,or x not finite */ (hy>0x7ff0000000000000LL),0)) /* or y is NaN */ return (x*y)/(x*y); - if(__builtin_expect(hx<=hy,0)) { - if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */ - if(lx==ly) - return Zero[(u_int64_t)sx>>63]; /* |x|=|y| return x*0*/ + if (__builtin_expect (hx <= hy, 0)) + { + /* If |x| < |y| return x. */ + if (hx < hy) + return x; + /* At this point the absolute value of the high doubles of + x and y must be equal. */ + /* If the low double of y is the same sign as the high + double of y (ie. the low double increases |y|)... */ + if (((ly ^ sy) & 0x8000000000000000LL) == 0 + /* ... then a different sign low double to high double + for x or same sign but lower magnitude... */ + && (int64_t) (lx ^ sx) < (int64_t) (ly ^ sy)) + /* ... means |x| < |y|. */ + return x; + /* If the low double of x differs in sign to the high + double of x (ie. the low double decreases |x|)... */ + if (((lx ^ sx) & 0x8000000000000000LL) != 0 + /* ... then a different sign low double to high double + for y with lower magnitude (we've already caught + the same sign for y case above)... */ + && (int64_t) (lx ^ sx) > (int64_t) (ly ^ sy)) + /* ... means |x| < |y|. */ + return x; + /* If |x| == |y| return x*0. */ + if ((lx ^ sx) == (ly ^ sy)) + return Zero[(uint64_t) sx >> 63]; } - /* determine ix = ilogb(x) */ - if(__builtin_expect(hx<0x0010000000000000LL,0)) { /* subnormal x */ - if(hx==0) { - for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; - } else { - for (ix = -1022, i=(hx<<11); i>0; i<<=1) ix -=1; - } - } else ix = (hx>>52)-0x3ff; - - /* determine iy = ilogb(y) */ - if(__builtin_expect(hy<0x0010000000000000LL,0)) { /* subnormal y */ - if(hy==0) { - for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; - } else { - for (iy = -1022, i=(hy<<11); i>0; i<<=1) iy -=1; - } - } else iy = (hy>>52)-0x3ff; - /* Make the IBM extended format 105 bit mantissa look like the ieee854 112 bit mantissa so the following operations will give the correct result. */ - ldbl_extract_mantissa(&hx, &lx, &temp, x); - ldbl_extract_mantissa(&hy, &ly, &temp, y); + ldbl_extract_mantissa(&hx, &lx, &ix, x); + ldbl_extract_mantissa(&hy, &ly, &iy, y); - /* set up {hx,lx}, {hy,ly} and align y to x */ - if(__builtin_expect(ix >= -1022, 1)) - hx = 0x0001000000000000LL|(0x0000ffffffffffffLL&hx); - else { /* subnormal x, shift x to normal */ - n = -1022-ix; - if(n<=63) { - hx = (hx<<n)|(lx>>(64-n)); - lx <<= n; - } else { - hx = lx<<(n-64); - lx = 0; - } - } - if(__builtin_expect(iy >= -1022, 1)) - hy = 0x0001000000000000LL|(0x0000ffffffffffffLL&hy); - else { /* subnormal y, shift y to normal */ - n = -1022-iy; - if(n<=63) { - hy = (hy<<n)|(ly>>(64-n)); - ly <<= n; - } else { - hy = ly<<(n-64); - ly = 0; - } - } + if (__builtin_expect (ix == -IEEE754_DOUBLE_BIAS, 0)) + { + /* subnormal x, shift x to normal. */ + while ((hx & (1LL << 48)) == 0) + { + hx = (hx << 1) | (lx >> 63); + lx = lx << 1; + ix -= 1; + } + } + + if (__builtin_expect (iy == -IEEE754_DOUBLE_BIAS, 0)) + { + /* subnormal y, shift y to normal. */ + while ((hy & (1LL << 48)) == 0) + { + hy = (hy << 1) | (ly >> 63); + ly = ly << 1; + iy -= 1; + } + } /* fix point fmod */ n = ix - iy; @@ -104,7 +111,7 @@ __ieee754_fmodl (long double x, long double y) hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; if(hz<0){hx = hx+hx+(lx>>63); lx = lx+lx;} else { - if((hz|(lz&0x7fffffffffffffff))==0) /* return sign(x)*0 */ + if((hz|lz)==0) /* return sign(x)*0 */ return Zero[(u_int64_t)sx>>63]; hx = hz+hz+(lz>>63); lx = lz+lz; } @@ -113,7 +120,7 @@ __ieee754_fmodl (long double x, long double y) if(hz>=0) {hx=hz;lx=lz;} /* convert back to floating value and restore the sign */ - if((hx|(lx&0x7fffffffffffffff))==0) /* return sign(x)*0 */ + if((hx|lx)==0) /* return sign(x)*0 */ return Zero[(u_int64_t)sx>>63]; while(hx<0x0001000000000000LL) { /* normalize x */ hx = hx+hx+(lx>>63); lx = lx+lx; diff --git a/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c b/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c index 90d8e3f0d2..84c13de9b8 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c @@ -122,11 +122,12 @@ long double __ieee754_gammal_r (long double x, int *signgamp) { int64_t hx; - u_int64_t lx; + double xhi; - GET_LDOUBLE_WORDS64 (hx, lx, x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); - if (((hx | lx) & 0x7fffffffffffffffLL) == 0) + if ((hx & 0x7fffffffffffffffLL) == 0) { /* Return value for x == 0 is Inf with divide by zero exception. */ *signgamp = 0; diff --git a/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c b/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c index 768bd3b06c..3b07a47b40 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c @@ -45,76 +45,84 @@ #include <math.h> #include <math_private.h> -static const long double two600 = 0x1.0p+600L; -static const long double two1022 = 0x1.0p+1022L; - long double __ieee754_hypotl(long double x, long double y) { - long double a,b,t1,t2,y1,y2,w,kld; + long double a,b,a1,a2,b1,b2,w,kld; int64_t j,k,ha,hb; + double xhi, yhi, hi, lo; - GET_LDOUBLE_MSW64(ha,x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (ha, xhi); + yhi = ldbl_high (y); + EXTRACT_WORDS64 (hb, yhi); ha &= 0x7fffffffffffffffLL; - GET_LDOUBLE_MSW64(hb,y); hb &= 0x7fffffffffffffffLL; if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} a = fabsl(a); /* a <- |a| */ b = fabsl(b); /* b <- |b| */ - if((ha-hb)>0x780000000000000LL) {return a+b;} /* x/y > 2**120 */ + if((ha-hb)>0x0780000000000000LL) {return a+b;} /* x/y > 2**120 */ k=0; kld = 1.0L; if(ha > 0x5f30000000000000LL) { /* a>2**500 */ if(ha >= 0x7ff0000000000000LL) { /* Inf or NaN */ - u_int64_t low; w = a+b; /* for sNaN */ - GET_LDOUBLE_LSW64(low,a); - if(((ha&0xfffffffffffffLL)|(low&0x7fffffffffffffffLL))==0) + if(ha == 0x7ff0000000000000LL) w = a; - GET_LDOUBLE_LSW64(low,b); - if(((hb^0x7ff0000000000000LL)|(low&0x7fffffffffffffffLL))==0) + if(hb == 0x7ff0000000000000LL) w = b; return w; } /* scale a and b by 2**-600 */ - ha -= 0x2580000000000000LL; hb -= 0x2580000000000000LL; k += 600; - a /= two600; - b /= two600; - k += 600; - kld = two600; + a *= 0x1p-600L; + b *= 0x1p-600L; + k = 600; + kld = 0x1p+600L; } - if(hb < 0x23d0000000000000LL) { /* b < 2**-450 */ + else if(hb < 0x23d0000000000000LL) { /* b < 2**-450 */ if(hb <= 0x000fffffffffffffLL) { /* subnormal b or 0 */ - u_int64_t low; - GET_LDOUBLE_LSW64(low,b); - if((hb|(low&0x7fffffffffffffffLL))==0) return a; - t1=two1022; /* t1=2^1022 */ - b *= t1; - a *= t1; - k -= 1022; - kld = kld / two1022; + if(hb==0) return a; + a *= 0x1p+1022L; + b *= 0x1p+1022L; + k = -1022; + kld = 0x1p-1022L; } else { /* scale a and b by 2^600 */ - ha += 0x2580000000000000LL; /* a *= 2^600 */ - hb += 0x2580000000000000LL; /* b *= 2^600 */ - k -= 600; - a *= two600; - b *= two600; - kld = kld / two600; + a *= 0x1p+600L; + b *= 0x1p+600L; + k = -600; + kld = 0x1p-600L; } } /* medium size a and b */ w = a-b; if (w>b) { - SET_LDOUBLE_WORDS64(t1,ha,0); - t2 = a-t1; - w = __ieee754_sqrtl(t1*t1-(b*(-b)-t2*(a+t1))); + ldbl_unpack (a, &hi, &lo); + a1 = hi; + a2 = lo; + /* a*a + b*b + = (a1+a2)*a + b*b + = a1*a + a2*a + b*b + = a1*(a1+a2) + a2*a + b*b + = a1*a1 + a1*a2 + a2*a + b*b + = a1*a1 + a2*(a+a1) + b*b */ + w = __ieee754_sqrtl(a1*a1-(b*(-b)-a2*(a+a1))); } else { a = a+a; - SET_LDOUBLE_WORDS64(y1,hb,0); - y2 = b - y1; - SET_LDOUBLE_WORDS64(t1,ha+0x0010000000000000LL,0); - t2 = a - t1; - w = __ieee754_sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b))); + ldbl_unpack (b, &hi, &lo); + b1 = hi; + b2 = lo; + ldbl_unpack (a, &hi, &lo); + a1 = hi; + a2 = lo; + /* a*a + b*b + = a*a + (a-b)*(a-b) - (a-b)*(a-b) + b*b + = a*a + w*w - (a*a - 2*a*b + b*b) + b*b + = w*w + 2*a*b + = w*w + (a1+a2)*b + = w*w + a1*b + a2*b + = w*w + a1*(b1+b2) + a2*b + = w*w + a1*b1 + a1*b2 + a2*b */ + w = __ieee754_sqrtl(a1*b1-(w*(-w)-(a1*b2+a2*b))); } if(k!=0) return w*kld; diff --git a/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c b/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c index 55f87ed422..aeace7c977 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c @@ -31,26 +31,24 @@ static char rcsid[] = "$NetBSD: $"; int __ieee754_ilogbl(long double x) { - int64_t hx,lx; + int64_t hx; int ix; + double xhi; - GET_LDOUBLE_WORDS64(hx,lx,x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); hx &= 0x7fffffffffffffffLL; if(hx <= 0x0010000000000000LL) { - if((hx|(lx&0x7fffffffffffffffLL))==0) + if(hx==0) return FP_ILOGB0; /* ilogbl(0) = FP_ILOGB0 */ else /* subnormal x */ - if(hx==0) { - for (ix = -1043; lx>0; lx<<=1) ix -=1; - } else { - for (ix = -1022, hx<<=11; hx>0; hx<<=1) ix -=1; - } + for (ix = -1022, hx<<=11; hx>0; hx<<=1) ix -=1; return ix; } else if (hx<0x7ff0000000000000LL) return (hx>>52)-0x3ff; else if (FP_ILOGBNAN != INT_MAX) { /* ISO C99 requires ilogbl(+-Inf) == INT_MAX. */ - if (((hx^0x7ff0000000000000LL)|lx) == 0) + if (hx==0x7ff0000000000000LL) return INT_MAX; } return FP_ILOGBNAN; diff --git a/sysdeps/ieee754/ldbl-128ibm/e_jnl.c b/sysdeps/ieee754/ldbl-128ibm/e_jnl.c index 40012e41e1..6761a0d26f 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_jnl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_jnl.c @@ -70,26 +70,25 @@ static const long double long double __ieee754_jnl (int n, long double x) { - u_int32_t se; + uint32_t se, lx; int32_t i, ix, sgn; long double a, b, temp, di; long double z, w; - ieee854_long_double_shape_type u; + double xhi; /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) * Thus, J(-n,x) = J(n,-x) */ - u.value = x; - se = u.parts32.w0; + xhi = ldbl_high (x); + EXTRACT_WORDS (se, lx, xhi); ix = se & 0x7fffffff; /* if J(n,NaN) is NaN */ if (ix >= 0x7ff00000) { - if ((u.parts32.w0 & 0xfffff) | u.parts32.w1 - | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) + if (((ix - 0x7ff00000) | lx) != 0) return x + x; } @@ -298,27 +297,26 @@ strong_alias (__ieee754_jnl, __jnl_finite) long double __ieee754_ynl (int n, long double x) { - u_int32_t se; + uint32_t se, lx; int32_t i, ix; int32_t sign; long double a, b, temp; - ieee854_long_double_shape_type u; + double xhi; - u.value = x; - se = u.parts32.w0; + xhi = ldbl_high (x); + EXTRACT_WORDS (se, lx, xhi); ix = se & 0x7fffffff; /* if Y(n,NaN) is NaN */ if (ix >= 0x7ff00000) { - if ((u.parts32.w0 & 0xfffff) | u.parts32.w1 - | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) + if (((ix - 0x7ff00000) | lx) != 0) return x + x; } if (x <= 0.0L) { if (x == 0.0L) - return -HUGE_VALL + x; + return ((n < 0 && (n & 1) != 0) ? 1.0L : -1.0L) / 0.0L; if (se & 0x80000000) return zero / (zero * x); } @@ -377,14 +375,16 @@ __ieee754_ynl (int n, long double x) a = __ieee754_y0l (x); b = __ieee754_y1l (x); /* quit if b is -inf */ - u.value = b; - se = u.parts32.w0 & 0xfff00000; + xhi = ldbl_high (b); + GET_HIGH_WORD (se, xhi); + se &= 0xfff00000; for (i = 1; i < n && se != 0xfff00000; i++) { temp = b; b = ((long double) (i + i) / x) * b - a; - u.value = b; - se = u.parts32.w0 & 0xfff00000; + xhi = ldbl_high (b); + GET_HIGH_WORD (se, xhi); + se &= 0xfff00000; a = temp; } } diff --git a/sysdeps/ieee754/ldbl-128ibm/e_log10l.c b/sysdeps/ieee754/ldbl-128ibm/e_log10l.c index fae774cea8..1a6a4a0fa3 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_log10l.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_log10l.c @@ -182,11 +182,13 @@ __ieee754_log10l (long double x) long double z; long double y; int e; - int64_t hx, lx; + int64_t hx; + double xhi; /* Test for domain */ - GET_LDOUBLE_WORDS64 (hx, lx, x); - if (((hx & 0x7fffffffffffffffLL) | (lx & 0x7fffffffffffffffLL)) == 0) + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); + if ((hx & 0x7fffffffffffffffLL) == 0) return (-1.0L / (x - x)); if (hx < 0) return (x - x) / (x - x); diff --git a/sysdeps/ieee754/ldbl-128ibm/e_log2l.c b/sysdeps/ieee754/ldbl-128ibm/e_log2l.c index f0098f6c73..323ded0c0f 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_log2l.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_log2l.c @@ -177,11 +177,13 @@ __ieee754_log2l (x) long double z; long double y; int e; - int64_t hx, lx; + int64_t hx; + double xhi; /* Test for domain */ - GET_LDOUBLE_WORDS64 (hx, lx, x); - if (((hx & 0x7fffffffffffffffLL) | (lx & 0x7fffffffffffffffLL)) == 0) + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); + if ((hx & 0x7fffffffffffffffLL) == 0) return (-1.0L / (x - x)); if (hx < 0) return (x - x) / (x - x); diff --git a/sysdeps/ieee754/ldbl-128ibm/e_logl.c b/sysdeps/ieee754/ldbl-128ibm/e_logl.c index 15b5edfab3..b7db2b9784 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_logl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_logl.c @@ -188,18 +188,20 @@ static const long double long double __ieee754_logl(long double x) { - long double z, y, w; - ieee854_long_double_shape_type u, t; + long double z, y, w, t; unsigned int m; int k, e; + double xhi; + uint32_t hx, lx; - u.value = x; - m = u.parts32.w0; + xhi = ldbl_high (x); + EXTRACT_WORDS (hx, lx, xhi); + m = hx; /* Check for IEEE special cases. */ k = m & 0x7fffffff; /* log(0) = -infinity. */ - if ((k | u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) == 0) + if ((k | lx) == 0) { return -0.5L / ZERO; } @@ -219,7 +221,7 @@ __ieee754_logl(long double x) { z = x - 1.0L; k = 64; - t.value = 1.0L; + t = 1.0L; e = 0; } else @@ -236,10 +238,8 @@ __ieee754_logl(long double x) k = (m - 0xff000) >> 13; /* t is the argument 0.5 + (k+26)/128 of the nearest item to u in the lookup table. */ - t.parts32.w0 = 0x3ff00000 + (k << 13); - t.parts32.w1 = 0; - t.parts32.w2 = 0; - t.parts32.w3 = 0; + INSERT_WORDS (xhi, 0x3ff00000 + (k << 13), 0); + t = xhi; w0 += 0x100000; e -= 1; k += 64; @@ -247,17 +247,15 @@ __ieee754_logl(long double x) else { k = (m - 0xfe000) >> 14; - t.parts32.w0 = 0x3fe00000 + (k << 14); - t.parts32.w1 = 0; - t.parts32.w2 = 0; - t.parts32.w3 = 0; + INSERT_WORDS (xhi, 0x3fe00000 + (k << 14), 0); + t = xhi; } - u.value = __scalbnl (u.value, ((int) ((w0 - u.parts32.w0) * 2)) >> 21); + x = __scalbnl (x, ((int) ((w0 - hx) * 2)) >> 21); /* log(u) = log( t u/t ) = log(t) + log(u/t) log(t) is tabulated in the lookup table. Express log(u/t) = log(1+z), where z = u/t - 1 = (u-t)/t. cf. Cody & Waite. */ - z = (u.value - t.value) / t.value; + z = (x - t) / t; } /* Series expansion of log(1+z). */ w = z * z; @@ -284,7 +282,7 @@ __ieee754_logl(long double x) y += e * ln2b; /* Base 2 exponent offset times ln(2). */ y += z; y += logtbl[k-26]; /* log(t) - (t-1) */ - y += (t.value - 1.0L); + y += (t - 1.0L); y += e * ln2a; return y; } diff --git a/sysdeps/ieee754/ldbl-128ibm/e_powl.c b/sysdeps/ieee754/ldbl-128ibm/e_powl.c index 8bd35d0c88..c942f2f249 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_powl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_powl.c @@ -151,37 +151,32 @@ __ieee754_powl (long double x, long double y) long double y1, t1, t2, r, s, t, u, v, w; long double s2, s_h, s_l, t_h, t_l, ay; int32_t i, j, k, yisint, n; - u_int32_t ix, iy; - int32_t hx, hy; - ieee854_long_double_shape_type o, p, q; + uint32_t ix, iy; + int32_t hx, hy, hax; + double ohi, xhi, xlo, yhi, ylo; + uint32_t lx, ly, lj; - p.value = x; - hx = p.parts32.w0; + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS (hx, lx, xhi); ix = hx & 0x7fffffff; - q.value = y; - hy = q.parts32.w0; + ldbl_unpack (y, &yhi, &ylo); + EXTRACT_WORDS (hy, ly, yhi); iy = hy & 0x7fffffff; - /* y==zero: x**0 = 1 */ - if ((iy | q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) == 0) + if ((iy | ly) == 0) return one; /* 1.0**y = 1; -1.0**+-Inf = 1 */ if (x == one) return one; - if (x == -1.0L && iy == 0x7ff00000 - && (q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) == 0) + if (x == -1.0L && ((iy - 0x7ff00000) | ly) == 0) return one; /* +-NaN return x+y */ - if ((ix > 0x7ff00000) - || ((ix == 0x7ff00000) - && ((p.parts32.w1 | (p.parts32.w2 & 0x7fffffff) | p.parts32.w3) != 0)) - || (iy > 0x7ff00000) - || ((iy == 0x7ff00000) - && ((q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) != 0))) + if ((ix >= 0x7ff00000 && ((ix - 0x7ff00000) | lx) != 0) + || (iy >= 0x7ff00000 && ((iy - 0x7ff00000) | ly) != 0)) return x + y; /* determine if y is an odd int when x < 0 @@ -192,7 +187,10 @@ __ieee754_powl (long double x, long double y) yisint = 0; if (hx < 0) { - if ((q.parts32.w2 & 0x7fffffff) >= 0x43400000) /* Low part >= 2^53 */ + uint32_t low_ye; + + GET_HIGH_WORD (low_ye, ylo); + if ((low_ye & 0x7fffffff) >= 0x43400000) /* Low part >= 2^53 */ yisint = 2; /* even integer y */ else if (iy >= 0x3ff00000) /* 1.0 */ { @@ -207,42 +205,43 @@ __ieee754_powl (long double x, long double y) } } + ax = fabsl (x); + /* special value of y */ - if ((q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) == 0) + if (ly == 0) { - if (iy == 0x7ff00000 && q.parts32.w1 == 0) /* y is +-inf */ + if (iy == 0x7ff00000) /* y is +-inf */ { - if (((ix - 0x3ff00000) | p.parts32.w1 - | (p.parts32.w2 & 0x7fffffff) | p.parts32.w3) == 0) - return y - y; /* inf**+-1 is NaN */ - else if (ix > 0x3ff00000 || fabsl (x) > 1.0L) + if (ax > one) /* (|x|>1)**+-inf = inf,0 */ return (hy >= 0) ? y : zero; else /* (|x|<1)**-,+inf = inf,0 */ return (hy < 0) ? -y : zero; } - if (iy == 0x3ff00000) - { /* y is +-1 */ - if (hy < 0) - return one / x; - else - return x; - } - if (hy == 0x40000000) - return x * x; /* y is 2 */ - if (hy == 0x3fe00000) - { /* y is 0.5 */ - if (hx >= 0) /* x >= +0 */ - return __ieee754_sqrtl (x); + if (ylo == 0.0) + { + if (iy == 0x3ff00000) + { /* y is +-1 */ + if (hy < 0) + return one / x; + else + return x; + } + if (hy == 0x40000000) + return x * x; /* y is 2 */ + if (hy == 0x3fe00000) + { /* y is 0.5 */ + if (hx >= 0) /* x >= +0 */ + return __ieee754_sqrtl (x); + } } } - ax = fabsl (x); /* special value of x */ - if ((p.parts32.w1 | (p.parts32.w2 & 0x7fffffff) | p.parts32.w3) == 0) + if (lx == 0) { - if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) + if (ix == 0x7ff00000 || ix == 0 || (ix == 0x3ff00000 && xlo == 0.0)) { z = ax; /*x is +-0,+-inf,+-1 */ if (hy < 0) @@ -294,8 +293,8 @@ __ieee754_powl (long double x, long double y) { ax *= two113; n -= 113; - o.value = ax; - ix = o.parts32.w0; + ohi = ldbl_high (ax); + GET_HIGH_WORD (ix, ohi); } n += ((ix) >> 20) - 0x3ff; j = ix & 0x000fffff; @@ -312,26 +311,19 @@ __ieee754_powl (long double x, long double y) ix -= 0x00100000; } - o.value = ax; - o.value = __scalbnl (o.value, ((int) ((ix - o.parts32.w0) * 2)) >> 21); - ax = o.value; + ohi = ldbl_high (ax); + GET_HIGH_WORD (hax, ohi); + ax = __scalbnl (ax, ((int) ((ix - hax) * 2)) >> 21); /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */ u = ax - bp[k]; /* bp[0]=1.0, bp[1]=1.5 */ v = one / (ax + bp[k]); s = u * v; - s_h = s; + s_h = ldbl_high (s); - o.value = s_h; - o.parts32.w3 = 0; - o.parts32.w2 = 0; - s_h = o.value; /* t_h=ax+bp[k] High */ t_h = ax + bp[k]; - o.value = t_h; - o.parts32.w3 = 0; - o.parts32.w2 = 0; - t_h = o.value; + t_h = ldbl_high (t_h); t_l = ax - (t_h - bp[k]); s_l = v * ((u - s_h * t_h) - s_h * t_l); /* compute log(ax) */ @@ -342,30 +334,21 @@ __ieee754_powl (long double x, long double y) r += s_l * (s_h + s); s2 = s_h * s_h; t_h = 3.0 + s2 + r; - o.value = t_h; - o.parts32.w3 = 0; - o.parts32.w2 = 0; - t_h = o.value; + t_h = ldbl_high (t_h); t_l = r - ((t_h - 3.0) - s2); /* u+v = s*(1+...) */ u = s_h * t_h; v = s_l * t_h + t_l * s; /* 2/(3log2)*(s+...) */ p_h = u + v; - o.value = p_h; - o.parts32.w3 = 0; - o.parts32.w2 = 0; - p_h = o.value; + p_h = ldbl_high (p_h); p_l = v - (p_h - u); z_h = cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */ z_l = cp_l * p_h + p_l * cp + dp_l[k]; /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ t = (long double) n; t1 = (((z_h + z_l) + dp_h[k]) + t); - o.value = t1; - o.parts32.w3 = 0; - o.parts32.w2 = 0; - t1 = o.value; + t1 = ldbl_high (t1); t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); /* s (sign of result -ve**odd) = -1 else = 1 */ @@ -374,21 +357,16 @@ __ieee754_powl (long double x, long double y) s = -one; /* (-ve)**(odd int) */ /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ - y1 = y; - o.value = y1; - o.parts32.w3 = 0; - o.parts32.w2 = 0; - y1 = o.value; + y1 = ldbl_high (y); p_l = (y - y1) * t1 + y * t2; p_h = y1 * t1; z = p_l + p_h; - o.value = z; - j = o.parts32.w0; + ohi = ldbl_high (z); + EXTRACT_WORDS (j, lj, ohi); if (j >= 0x40d00000) /* z >= 16384 */ { /* if z > 16384 */ - if (((j - 0x40d00000) | o.parts32.w1 - | (o.parts32.w2 & 0x7fffffff) | o.parts32.w3) != 0) + if (((j - 0x40d00000) | lj) != 0) return s * huge * huge; /* overflow */ else { @@ -399,8 +377,7 @@ __ieee754_powl (long double x, long double y) else if ((j & 0x7fffffff) >= 0x40d01b90) /* z <= -16495 */ { /* z < -16495 */ - if (((j - 0xc0d01bc0) | o.parts32.w1 - | (o.parts32.w2 & 0x7fffffff) | o.parts32.w3) != 0) + if (((j - 0xc0d01bc0) | lj) != 0) return s * tiny * tiny; /* underflow */ else { @@ -419,10 +396,7 @@ __ieee754_powl (long double x, long double y) p_h -= t; } t = p_l + p_h; - o.value = t; - o.parts32.w3 = 0; - o.parts32.w2 = 0; - t = o.value; + t = ldbl_high (t); u = t * lg2_h; v = (p_l - (t - p_h)) * lg2 + t * lg2_l; z = u + v; diff --git a/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c b/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c index 6a72d6a853..36bc03226b 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c @@ -200,10 +200,11 @@ int32_t __ieee754_rem_pio2l(long double x, long double *y) double tx[8]; int exp; int64_t n, ix, hx, ixd; - u_int64_t lx __attribute__ ((unused)); u_int64_t lxd; + double xhi; - GET_LDOUBLE_WORDS64 (hx, lx, x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); ix = hx & 0x7fffffffffffffffLL; if (ix <= 0x3fe921fb54442d10LL) /* x in <-pi/4, pi/4> */ { @@ -243,7 +244,7 @@ int32_t __ieee754_rem_pio2l(long double x, long double *y) We split the 113 bits of the mantissa into 5 24bit integers stored in a double array. */ /* Make the IBM extended format 105 bit mantissa look like the ieee854 112 - bit mantissa so the next operatation will give the correct result. */ + bit mantissa so the next operation will give the correct result. */ ldbl_extract_mantissa (&ixd, &lxd, &exp, x); exp = exp - 23; /* This is faster than doing this in floating point, because we diff --git a/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c b/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c index 67d7db7fbe..800416f29a 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c @@ -33,18 +33,22 @@ __ieee754_remainderl(long double x, long double p) int64_t hx,hp; u_int64_t sx,lx,lp; long double p_half; + double xhi, xlo, phi, plo; - GET_LDOUBLE_WORDS64(hx,lx,x); - GET_LDOUBLE_WORDS64(hp,lp,p); + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS64 (hx, xhi); + EXTRACT_WORDS64 (lx, xlo); + ldbl_unpack (p, &phi, &plo); + EXTRACT_WORDS64 (hp, phi); + EXTRACT_WORDS64 (lp, plo); sx = hx&0x8000000000000000ULL; hp &= 0x7fffffffffffffffLL; hx &= 0x7fffffffffffffffLL; /* purge off exception values */ - if((hp|(lp&0x7fffffffffffffff))==0) return (x*p)/(x*p); /* p = 0 */ + if(hp==0) return (x*p)/(x*p); /* p = 0 */ if((hx>=0x7ff0000000000000LL)|| /* x not finite */ - ((hp>=0x7ff0000000000000LL)&& /* p is NaN */ - (((hp-0x7ff0000000000000LL)|lp)!=0))) + (hp>0x7ff0000000000000LL)) /* p is NaN */ return (x*p)/(x*p); @@ -64,8 +68,8 @@ __ieee754_remainderl(long double x, long double p) if(x>=p_half) x -= p; } } - GET_LDOUBLE_MSW64(hx,x); - SET_LDOUBLE_MSW64(x,hx^sx); + if (sx) + x = -x; return x; } strong_alias (__ieee754_remainderl, __remainderl_finite) diff --git a/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c b/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c index 4e8481c419..1790bef87e 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c @@ -38,9 +38,11 @@ __ieee754_sinhl(long double x) { long double t,w,h; int64_t ix,jx; + double xhi; /* High word of |x|. */ - GET_LDOUBLE_MSW64(jx,x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (jx, xhi); ix = jx&0x7fffffffffffffffLL; /* x is INF or NaN */ diff --git a/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c b/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c index 2b0f7c62e4..61feb367f7 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c @@ -34,15 +34,13 @@ #include <math_private.h> -typedef unsigned int int4; -typedef union {int4 i[4]; long double x; double d[2]; } mynumber; +typedef union {int64_t i[2]; long double x; double d[2]; } mynumber; -static const mynumber - t512 = {{0x5ff00000, 0x00000000, 0x00000000, 0x00000000 }}, /* 2^512 */ - tm256 = {{0x2ff00000, 0x00000000, 0x00000000, 0x00000000 }}; /* 2^-256 */ static const double -two54 = 1.80143985094819840000e+16, /* 0x4350000000000000 */ -twom54 = 5.55111512312578270212e-17; /* 0x3C90000000000000 */ + t512 = 0x1p512, + tm256 = 0x1p-256, + two54 = 0x1p54, /* 0x4350000000000000 */ + twom54 = 0x1p-54; /* 0x3C90000000000000 */ /*********************************************************************/ /* An ultimate sqrt routine. Given an IEEE double machine number x */ @@ -54,56 +52,53 @@ long double __ieee754_sqrtl(long double x) static const long double big = 134217728.0, big1 = 134217729.0; long double t,s,i; mynumber a,c; - int4 k, l, m; - int n; + uint64_t k, l; + int64_t m, n; double d; a.x=x; - k=a.i[0] & 0x7fffffff; + k=a.i[0] & INT64_C(0x7fffffffffffffff); /*----------------- 2^-1022 <= | x |< 2^1024 -----------------*/ - if (k>0x000fffff && k<0x7ff00000) { + if (k>INT64_C(0x000fffff00000000) && k<INT64_C(0x7ff0000000000000)) { if (x < 0) return (big1-big1)/(big-big); - l = (k&0x001fffff)|0x3fe00000; - if (((a.i[2] & 0x7fffffff) | a.i[3]) != 0) { - n = (int) ((l - k) * 2) >> 21; - m = (a.i[2] >> 20) & 0x7ff; + l = (k&INT64_C(0x001fffffffffffff))|INT64_C(0x3fe0000000000000); + if ((a.i[1] & INT64_C(0x7fffffffffffffff)) != 0) { + n = (int64_t) ((l - k) * 2) >> 53; + m = (a.i[1] >> 52) & 0x7ff; if (m == 0) { a.d[1] *= two54; - m = ((a.i[2] >> 20) & 0x7ff) - 54; + m = ((a.i[1] >> 52) & 0x7ff) - 54; } m += n; - if ((int) m > 0) - a.i[2] = (a.i[2] & 0x800fffff) | (m << 20); - else if ((int) m <= -54) { - a.i[2] &= 0x80000000; - a.i[3] = 0; + if (m > 0) + a.i[1] = (a.i[1] & INT64_C(0x800fffffffffffff)) | (m << 52); + else if (m <= -54) { + a.i[1] &= INT64_C(0x8000000000000000); } else { m += 54; - a.i[2] = (a.i[2] & 0x800fffff) | (m << 20); + a.i[1] = (a.i[1] & INT64_C(0x800fffffffffffff)) | (m << 52); a.d[1] *= twom54; } } a.i[0] = l; s = a.x; d = __ieee754_sqrt (a.d[0]); - c.i[0] = 0x20000000+((k&0x7fe00000)>>1); + c.i[0] = INT64_C(0x2000000000000000)+((k&INT64_C(0x7fe0000000000000))>>1); c.i[1] = 0; - c.i[2] = 0; - c.i[3] = 0; i = d; t = 0.5L * (i + s / i); i = 0.5L * (t + s / t); return c.x * i; } else { - if (k>=0x7ff00000) { - if (a.i[0] == 0xfff00000 && a.i[1] == 0) + if (k>=INT64_C(0x7ff0000000000000)) { + if (a.i[0] == INT64_C(0xfff0000000000000)) return (big1-big1)/(big-big); /* sqrt (-Inf) = NaN. */ return x; /* sqrt (NaN) = NaN, sqrt (+Inf) = +Inf. */ } if (x == 0) return x; if (x < 0) return (big1-big1)/(big-big); - return tm256.x*__ieee754_sqrtl(x*t512.x); + return tm256*__ieee754_sqrtl(x*t512); } } strong_alias (__ieee754_sqrtl, __sqrtl_finite) diff --git a/sysdeps/ieee754/ldbl-128ibm/ieee754.h b/sysdeps/ieee754/ldbl-128ibm/ieee754.h index 9e94f53b04..0c97a99207 100644 --- a/sysdeps/ieee754/ldbl-128ibm/ieee754.h +++ b/sysdeps/ieee754/ldbl-128ibm/ieee754.h @@ -111,61 +111,6 @@ union ieee754_double #define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */ -union ieee854_long_double - { - long double d; - - /* This is the IEEE 854 quad-precision format. */ - struct - { -#if __BYTE_ORDER == __BIG_ENDIAN - unsigned int negative:1; - unsigned int exponent:15; - /* Together these comprise the mantissa. */ - unsigned int mantissa0:16; - unsigned int mantissa1:32; - unsigned int mantissa2:32; - unsigned int mantissa3:32; -#endif /* Big endian. */ -#if __BYTE_ORDER == __LITTLE_ENDIAN - /* Together these comprise the mantissa. */ - unsigned int mantissa3:32; - unsigned int mantissa2:32; - unsigned int mantissa1:32; - unsigned int mantissa0:16; - unsigned int exponent:15; - unsigned int negative:1; -#endif /* Little endian. */ - } ieee; - - /* This format makes it easier to see if a NaN is a signalling NaN. */ - struct - { -#if __BYTE_ORDER == __BIG_ENDIAN - unsigned int negative:1; - unsigned int exponent:15; - unsigned int quiet_nan:1; - /* Together these comprise the mantissa. */ - unsigned int mantissa0:15; - unsigned int mantissa1:32; - unsigned int mantissa2:32; - unsigned int mantissa3:32; -#else - /* Together these comprise the mantissa. */ - unsigned int mantissa3:32; - unsigned int mantissa2:32; - unsigned int mantissa1:32; - unsigned int mantissa0:15; - unsigned int quiet_nan:1; - unsigned int exponent:15; - unsigned int negative:1; -#endif - } ieee_nan; - }; - -#define IEEE854_LONG_DOUBLE_BIAS 0x3fff /* Added to exponent. */ - - /* IBM extended format for long double. Each long double is made up of two IEEE doubles. The value of the @@ -179,49 +124,10 @@ union ieee854_long_double union ibm_extended_long_double { - long double d; - double dd[2]; - - /* This is the IBM extended format long double. */ - struct - { /* Big endian. There is no other. */ - - unsigned int negative:1; - unsigned int exponent:11; - /* Together Mantissa0-3 comprise the mantissa. */ - unsigned int mantissa0:20; - unsigned int mantissa1:32; - - unsigned int negative2:1; - unsigned int exponent2:11; - /* There is an implied 1 here? */ - /* Together these comprise the mantissa. */ - unsigned int mantissa2:20; - unsigned int mantissa3:32; - } ieee; - - /* This format makes it easier to see if a NaN is a signalling NaN. */ - struct - { /* Big endian. There is no other. */ - - unsigned int negative:1; - unsigned int exponent:11; - unsigned int quiet_nan:1; - /* Together Mantissa0-3 comprise the mantissa. */ - unsigned int mantissa0:19; - unsigned int mantissa1:32; - - unsigned int negative2:1; - unsigned int exponent2:11; - /* There is an implied 1 here? */ - /* Together these comprise the mantissa. */ - unsigned int mantissa2:20; - unsigned int mantissa3:32; - } ieee_nan; + long double ld; + union ieee754_double d[2]; }; -#define IBM_EXTENDED_LONG_DOUBLE_BIAS 0x3ff /* Added to exponent. */ - __END_DECLS #endif /* ieee754.h */ diff --git a/sysdeps/ieee754/ldbl-128ibm/k_cosl.c b/sysdeps/ieee754/ldbl-128ibm/k_cosl.c index 0b81782fdb..046f3b573c 100644 --- a/sysdeps/ieee754/ldbl-128ibm/k_cosl.c +++ b/sysdeps/ieee754/ldbl-128ibm/k_cosl.c @@ -81,8 +81,11 @@ __kernel_cosl(long double x, long double y) { long double h, l, z, sin_l, cos_l_m1; int64_t ix; - u_int32_t tix, hix, index; - GET_LDOUBLE_MSW64 (ix, x); + uint32_t tix, hix, index; + double xhi, hhi; + + xhi = ldbl_high (x); + EXTRACT_WORDS64 (ix, xhi); tix = ((u_int64_t)ix) >> 32; tix &= ~0x80000000; /* tix = |x|'s high 32 bits */ if (tix < 0x3fc30000) /* |x| < 0.1484375 */ @@ -136,7 +139,8 @@ __kernel_cosl(long double x, long double y) case 2: index = (hix - 0x3fc30000) >> 14; break; } */ - SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0); + INSERT_WORDS64 (hhi, ((uint64_t)hix) << 32); + h = hhi; l = y - (h - x); z = l * l; sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5))))); diff --git a/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c b/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c index fc1ead6597..3ba9d7e907 100644 --- a/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c +++ b/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c @@ -100,9 +100,12 @@ __kernel_sincosl(long double x, long double y, long double *sinx, long double *c { long double h, l, z, sin_l, cos_l_m1; int64_t ix; - u_int32_t tix, hix, index; - GET_LDOUBLE_MSW64 (ix, x); - tix = ((u_int64_t)ix) >> 32; + uint32_t tix, hix, index; + double xhi, hhi; + + xhi = ldbl_high (x); + EXTRACT_WORDS64 (ix, xhi); + tix = ((uint64_t)ix) >> 32; tix &= ~0x80000000; /* tix = |x|'s high 32 bits */ if (tix < 0x3fc30000) /* |x| < 0.1484375 */ { @@ -164,7 +167,8 @@ __kernel_sincosl(long double x, long double y, long double *sinx, long double *c case 2: index = (hix - 0x3fc30000) >> 14; break; } */ - SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0); + INSERT_WORDS64 (hhi, ((uint64_t)hix) << 32); + h = hhi; if (iy) l = y - (h - x); else diff --git a/sysdeps/ieee754/ldbl-128ibm/k_sinl.c b/sysdeps/ieee754/ldbl-128ibm/k_sinl.c index f17c0ae5db..b12ea134d5 100644 --- a/sysdeps/ieee754/ldbl-128ibm/k_sinl.c +++ b/sysdeps/ieee754/ldbl-128ibm/k_sinl.c @@ -82,7 +82,10 @@ __kernel_sinl(long double x, long double y, int iy) long double h, l, z, sin_l, cos_l_m1; int64_t ix; u_int32_t tix, hix, index; - GET_LDOUBLE_MSW64 (ix, x); + double xhi, hhi; + + xhi = ldbl_high (x); + EXTRACT_WORDS64 (ix, xhi); tix = ((u_int64_t)ix) >> 32; tix &= ~0x80000000; /* tix = |x|'s high 32 bits */ if (tix < 0x3fc30000) /* |x| < 0.1484375 */ @@ -132,7 +135,8 @@ __kernel_sinl(long double x, long double y, int iy) case 2: index = (hix - 0x3fc30000) >> 14; break; } */ - SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0); + INSERT_WORDS64 (hhi, ((uint64_t)hix) << 32); + h = hhi; if (iy) l = (ix < 0 ? -y : y) - (h - x); else diff --git a/sysdeps/ieee754/ldbl-128ibm/k_tanl.c b/sysdeps/ieee754/ldbl-128ibm/k_tanl.c index 1f6bad241b..bcf8b5e7d6 100644 --- a/sysdeps/ieee754/ldbl-128ibm/k_tanl.c +++ b/sysdeps/ieee754/ldbl-128ibm/k_tanl.c @@ -85,17 +85,17 @@ long double __kernel_tanl (long double x, long double y, int iy) { long double z, r, v, w, s; - int32_t ix, sign; - ieee854_long_double_shape_type u, u1; + int32_t ix, sign, hx, lx; + double xhi; - u.value = x; - ix = u.parts32.w0 & 0x7fffffff; + xhi = ldbl_high (x); + EXTRACT_WORDS (hx, lx, xhi); + ix = hx & 0x7fffffff; if (ix < 0x3c600000) /* x < 2**-57 */ { - if ((int) x == 0) - { /* generate inexact */ - if ((ix | u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3 - | (iy + 1)) == 0) + if ((int) x == 0) /* generate inexact */ + { + if ((ix | lx | (iy + 1)) == 0) return one / fabs (x); else return (iy == 1) ? x : -one / x; @@ -103,7 +103,7 @@ __kernel_tanl (long double x, long double y, int iy) } if (ix >= 0x3fe59420) /* |x| >= 0.6743316650390625 */ { - if ((u.parts32.w0 & 0x80000000) != 0) + if ((hx & 0x80000000) != 0) { x = -x; y = -y; @@ -139,15 +139,13 @@ __kernel_tanl (long double x, long double y, int iy) { /* if allow error up to 2 ulp, simply return -1.0/(x+r) here */ /* compute -1.0/(x+r) accurately */ - u1.value = w; - u1.parts32.w2 = 0; - u1.parts32.w3 = 0; - v = r - (u1.value - x); /* u1+v = r+x */ + long double u1, z1; + + u1 = ldbl_high (w); + v = r - (u1 - x); /* u1+v = r+x */ z = -1.0 / w; - u.value = z; - u.parts32.w2 = 0; - u.parts32.w3 = 0; - s = 1.0 + u.value * u1.value; - return u.value + z * (s + u.value * v); + z1 = ldbl_high (z); + s = 1.0 + z1 * u1; + return z1 + z * (s + z1 * v); } } diff --git a/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c b/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c index 00e44b8b92..e46fde74fc 100644 --- a/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c +++ b/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c @@ -36,34 +36,44 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size, union ibm_extended_long_double u; unsigned long long hi, lo; int ediff; - u.d = value; - *is_neg = u.ieee.negative; - *expt = (int) u.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS; + u.ld = value; - lo = ((long long) u.ieee.mantissa2 << 32) | u.ieee.mantissa3; - hi = ((long long) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; - /* If the lower double is not a denomal or zero then set the hidden + *is_neg = u.d[0].ieee.negative; + *expt = (int) u.d[0].ieee.exponent - IEEE754_DOUBLE_BIAS; + + lo = ((long long) u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1; + hi = ((long long) u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1; + + /* If the lower double is not a denormal or zero then set the hidden 53rd bit. */ - if (u.ieee.exponent2 > 0) - { - lo |= 1LL << 52; + if (u.d[1].ieee.exponent != 0) + lo |= 1ULL << 52; + else + lo = lo << 1; - /* The lower double is normalized separately from the upper. We may - need to adjust the lower manitissa to reflect this. */ - ediff = u.ieee.exponent - u.ieee.exponent2; - if (ediff > 53) - lo = lo >> (ediff-53); + /* The lower double is normalized separately from the upper. We may + need to adjust the lower manitissa to reflect this. */ + ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53; + if (ediff > 0) + { + if (ediff < 64) + lo = lo >> ediff; + else + lo = 0; } + else if (ediff < 0) + lo = lo << -ediff; + /* The high double may be rounded and the low double reflects the difference between the long double and the rounded high double value. This is indicated by a differnce between the signs of the high and low doubles. */ - if ((u.ieee.negative != u.ieee.negative2) - && ((u.ieee.exponent2 != 0) && (lo != 0L))) + if (u.d[0].ieee.negative != u.d[1].ieee.negative + && lo != 0) { lo = (1ULL << 53) - lo; - if (hi == 0LL) + if (hi == 0) { /* we have a borrow from the hidden bit, so shift left 1. */ hi = 0x0ffffffffffffeLL | (lo >> 51); @@ -92,7 +102,7 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size, #define NUM_LEADING_ZEROS (BITS_PER_MP_LIMB \ - (LDBL_MANT_DIG - ((N - 1) * BITS_PER_MP_LIMB))) - if (u.ieee.exponent == 0) + if (u.d[0].ieee.exponent == 0) { /* A biased exponent of zero is a special case. Either it is a zero or it is a denormal number. */ diff --git a/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h b/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h index 046293e598..1b6e27a9ff 100644 --- a/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h +++ b/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h @@ -2,10 +2,13 @@ #error "Never use <math_ldbl.h> directly; include <math_private.h> instead." #endif -#include <sysdeps/ieee754/ldbl-128/math_ldbl.h> #include <ieee754.h> #include <stdint.h> +/* To suit our callers we return *hi64 and *lo64 as if they came from + an ieee854 112 bit mantissa, that is, 48 bits in *hi64 (plus one + implicit bit) and 64 bits in *lo64. */ + static inline void ldbl_extract_mantissa (int64_t *hi64, uint64_t *lo64, int *exp, long double x) { @@ -14,77 +17,119 @@ ldbl_extract_mantissa (int64_t *hi64, uint64_t *lo64, int *exp, long double x) the number before the decimal point and the second implicit bit as bit 53 of the mantissa. */ uint64_t hi, lo; - int ediff; - union ibm_extended_long_double eldbl; - eldbl.d = x; - *exp = eldbl.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS; - - lo = ((int64_t)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; - hi = ((int64_t)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; - /* If the lower double is not a denomal or zero then set the hidden - 53rd bit. */ - if (eldbl.ieee.exponent2 > 0x001) - { - lo |= (1ULL << 52); - lo = lo << 7; /* pre-shift lo to match ieee854. */ - /* The lower double is normalized separately from the upper. We - may need to adjust the lower manitissa to reflect this. */ - ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; - if (ediff > 53) - lo = lo >> (ediff-53); - hi |= (1ULL << 52); - } + union ibm_extended_long_double u; - if ((eldbl.ieee.negative != eldbl.ieee.negative2) - && ((eldbl.ieee.exponent2 != 0) && (lo != 0LL))) + u.ld = x; + *exp = u.d[0].ieee.exponent - IEEE754_DOUBLE_BIAS; + + lo = ((uint64_t) u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1; + hi = ((uint64_t) u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1; + + if (u.d[0].ieee.exponent != 0) { - hi--; - lo = (1ULL << 60) - lo; - if (hi < (1ULL << 52)) + int ediff; + + /* If not a denormal or zero then we have an implicit 53rd bit. */ + hi |= (uint64_t) 1 << 52; + + if (u.d[1].ieee.exponent != 0) + lo |= (uint64_t) 1 << 52; + else + /* A denormal is to be interpreted as having a biased exponent + of 1. */ + lo = lo << 1; + + /* We are going to shift 4 bits out of hi later, because we only + want 48 bits in *hi64. That means we want 60 bits in lo, but + we currently only have 53. Shift the value up. */ + lo = lo << 7; + + /* The lower double is normalized separately from the upper. + We may need to adjust the lower mantissa to reflect this. + The difference between the exponents can be larger than 53 + when the low double is much less than 1ULP of the upper + (in which case there are significant bits, all 0's or all + 1's, between the two significands). The difference between + the exponents can be less than 53 when the upper double + exponent is nearing its minimum value (in which case the low + double is denormal ie. has an exponent of zero). */ + ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53; + if (ediff > 0) + { + if (ediff < 64) + lo = lo >> ediff; + else + lo = 0; + } + else if (ediff < 0) + lo = lo << -ediff; + + if (u.d[0].ieee.negative != u.d[1].ieee.negative + && lo != 0) { - /* we have a borrow from the hidden bit, so shift left 1. */ - hi = (hi << 1) | (lo >> 59); - lo = 0xfffffffffffffffLL & (lo << 1); - *exp = *exp - 1; + hi--; + lo = ((uint64_t) 1 << 60) - lo; + if (hi < (uint64_t) 1 << 52) + { + /* We have a borrow from the hidden bit, so shift left 1. */ + hi = (hi << 1) | (lo >> 59); + lo = (((uint64_t) 1 << 60) - 1) & (lo << 1); + *exp = *exp - 1; + } } } + else + /* If the larger magnitude double is denormal then the smaller + one must be zero. */ + hi = hi << 1; + *lo64 = (hi << 60) | lo; *hi64 = hi >> 4; } static inline long double -ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64) +ldbl_insert_mantissa (int sign, int exp, int64_t hi64, uint64_t lo64) { union ibm_extended_long_double u; - unsigned long hidden2, lzcount; - unsigned long long hi, lo; + int expnt2; + uint64_t hi, lo; + + u.d[0].ieee.negative = sign; + u.d[1].ieee.negative = sign; + u.d[0].ieee.exponent = exp + IEEE754_DOUBLE_BIAS; + u.d[1].ieee.exponent = 0; + expnt2 = exp - 53 + IEEE754_DOUBLE_BIAS; - u.ieee.negative = sign; - u.ieee.negative2 = sign; - u.ieee.exponent = exp + IBM_EXTENDED_LONG_DOUBLE_BIAS; - u.ieee.exponent2 = exp-53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; /* Expect 113 bits (112 bits + hidden) right justified in two longs. The low order 53 bits (52 + hidden) go into the lower double */ - lo = (lo64 >> 7)& ((1ULL << 53) - 1); - hidden2 = (lo64 >> 59) & 1ULL; + lo = (lo64 >> 7) & (((uint64_t) 1 << 53) - 1); /* The high order 53 bits (52 + hidden) go into the upper double */ - hi = (lo64 >> 60) & ((1ULL << 11) - 1); - hi |= (hi64 << 4); + hi = lo64 >> 60; + hi |= hi64 << 4; - if (lo != 0LL) + if (lo != 0) { - /* hidden2 bit of low double controls rounding of the high double. - If hidden2 is '1' then round up hi and adjust lo (2nd mantissa) + int lzcount; + + /* hidden bit of low double controls rounding of the high double. + If hidden is '1' and either the explicit mantissa is non-zero + or hi is odd, then round up hi and adjust lo (2nd mantissa) plus change the sign of the low double to compensate. */ - if (hidden2) + if ((lo & ((uint64_t) 1 << 52)) != 0 + && ((hi & 1) != 0 || (lo & (((uint64_t) 1 << 52) - 1)) != 0)) { hi++; - u.ieee.negative2 = !sign; - lo = (1ULL << 53) - lo; + if ((hi & ((uint64_t) 1 << 53)) != 0) + { + hi = hi >> 1; + u.d[0].ieee.exponent++; + } + u.d[1].ieee.negative = !sign; + lo = ((uint64_t) 1 << 53) - lo; } - /* The hidden bit of the lo mantissa is zero so we need to - normalize the it for the low double. Shift it left until the - hidden bit is '1' then adjust the 2nd exponent accordingly. */ + + /* Normalize the low double. Shift the mantissa left until + the hidden bit is '1' and adjust the exponent accordingly. */ if (sizeof (lo) == sizeof (long)) lzcount = __builtin_clzl (lo); @@ -92,35 +137,31 @@ ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64) lzcount = __builtin_clzl ((long) (lo >> 32)); else lzcount = __builtin_clzl ((long) lo) + 32; - lzcount = lzcount - 11; - if (lzcount > 0) + lzcount = lzcount - (64 - 53); + lo <<= lzcount; + expnt2 -= lzcount; + + if (expnt2 >= 1) + /* Not denormal. */ + u.d[1].ieee.exponent = expnt2; + else { - int expnt2 = u.ieee.exponent2 - lzcount; - if (expnt2 >= 1) - { - /* Not denormal. Normalize and set low exponent. */ - lo = lo << lzcount; - u.ieee.exponent2 = expnt2; - } + /* Is denormal. Note that biased exponent of 0 is treated + as if it was 1, hence the extra shift. */ + if (expnt2 > -53) + lo >>= 1 - expnt2; else - { - /* Is denormal. */ - lo = lo << (lzcount + expnt2); - u.ieee.exponent2 = 0; - } + lo = 0; } } else - { - u.ieee.negative2 = 0; - u.ieee.exponent2 = 0; - } + u.d[1].ieee.negative = 0; - u.ieee.mantissa3 = lo & ((1ULL << 32) - 1); - u.ieee.mantissa2 = (lo >> 32) & ((1ULL << 20) - 1); - u.ieee.mantissa1 = hi & ((1ULL << 32) - 1); - u.ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1); - return u.d; + u.d[1].ieee.mantissa1 = lo; + u.d[1].ieee.mantissa0 = lo >> 32; + u.d[0].ieee.mantissa1 = hi; + u.d[0].ieee.mantissa0 = hi >> 32; + return u.ld; } /* Handy utility functions to pack/unpack/cononicalize and find the nearbyint @@ -129,18 +170,18 @@ static inline long double default_ldbl_pack (double a, double aa) { union ibm_extended_long_double u; - u.dd[0] = a; - u.dd[1] = aa; - return u.d; + u.d[0].d = a; + u.d[1].d = aa; + return u.ld; } static inline void default_ldbl_unpack (long double l, double *a, double *aa) { union ibm_extended_long_double u; - u.d = l; - *a = u.dd[0]; - *aa = u.dd[1]; + u.ld = l; + *a = u.d[0].d; + *aa = u.d[1].d; } #ifndef ldbl_pack @@ -150,6 +191,9 @@ default_ldbl_unpack (long double l, double *a, double *aa) # define ldbl_unpack default_ldbl_unpack #endif +/* Extract high double. */ +#define ldbl_high(x) ((double) x) + /* Convert a finite long double to canonical form. Does not handle +/-Inf properly. */ static inline void @@ -163,13 +207,13 @@ ldbl_canonicalize (double *a, double *aa) *aa = xl; } -/* Simple inline nearbyint (double) function . +/* Simple inline nearbyint (double) function. Only works in the default rounding mode but is useful in long double rounding functions. */ static inline double ldbl_nearbyint (double a) { - double two52 = 0x10000000000000LL; + double two52 = 0x1p52; if (__builtin_expect ((__builtin_fabs (a) < two52), 1)) { diff --git a/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c b/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c index 3df42c5666..c96852dfd9 100644 --- a/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c +++ b/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c @@ -33,11 +33,11 @@ __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign) unsigned long long hi, lo; int exponent2; - u.ieee.negative = sign; - u.ieee.negative2 = sign; - u.ieee.exponent = expt + IBM_EXTENDED_LONG_DOUBLE_BIAS; - u.ieee.exponent2 = 0; - exponent2 = expt - 53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; + u.d[0].ieee.negative = sign; + u.d[1].ieee.negative = sign; + u.d[0].ieee.exponent = expt + IEEE754_DOUBLE_BIAS; + u.d[1].ieee.exponent = 0; + exponent2 = expt - 53 + IEEE754_DOUBLE_BIAS; #if BITS_PER_MP_LIMB == 32 /* The low order 53 bits (52 + hidden) go into the lower double */ @@ -69,19 +69,19 @@ __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign) else lzcount = __builtin_clzl ((long) val) + 32; if (hi) - lzcount = lzcount - 11; + lzcount = lzcount - (64 - 53); else - lzcount = lzcount + 42; + lzcount = lzcount + 53 - (64 - 53); - if (lzcount > u.ieee.exponent) + if (lzcount > u.d[0].ieee.exponent) { - lzcount = u.ieee.exponent; - u.ieee.exponent = 0; + lzcount = u.d[0].ieee.exponent; + u.d[0].ieee.exponent = 0; exponent2 -= lzcount; } else { - u.ieee.exponent -= (lzcount - 1); + u.d[0].ieee.exponent -= (lzcount - 1); exponent2 -= (lzcount - 1); } @@ -97,29 +97,27 @@ __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign) } } - if (lo != 0L) + if (lo != 0) { - /* hidden2 bit of low double controls rounding of the high double. - If hidden2 is '1' and either the explicit mantissa is non-zero + /* hidden bit of low double controls rounding of the high double. + If hidden is '1' and either the explicit mantissa is non-zero or hi is odd, then round up hi and adjust lo (2nd mantissa) plus change the sign of the low double to compensate. */ if ((lo & (1LL << 52)) != 0 - && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1)))) + && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1)) != 0)) { hi++; - if ((hi & ((1LL << 52) - 1)) == 0) + if ((hi & (1LL << 53)) != 0) { - if ((hi & (1LL << 53)) != 0) - hi -= 1LL << 52; - u.ieee.exponent++; + hi >>= 1; + u.d[0].ieee.exponent++; } - u.ieee.negative2 = !sign; + u.d[1].ieee.negative = !sign; lo = (1LL << 53) - lo; } - /* The hidden bit of the lo mantissa is zero so we need to normalize - it for the low double. Shift it left until the hidden bit is '1' - then adjust the 2nd exponent accordingly. */ + /* Normalize the low double. Shift the mantissa left until + the hidden bit is '1' and adjust the exponent accordingly. */ if (sizeof (lo) == sizeof (long)) lzcount = __builtin_clzl (lo); @@ -127,24 +125,24 @@ __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign) lzcount = __builtin_clzl ((long) (lo >> 32)); else lzcount = __builtin_clzl ((long) lo) + 32; - lzcount = lzcount - 11; - if (lzcount > 0) - { - lo = lo << lzcount; - exponent2 = exponent2 - lzcount; - } + lzcount = lzcount - (64 - 53); + lo <<= lzcount; + exponent2 -= lzcount; + if (exponent2 > 0) - u.ieee.exponent2 = exponent2; - else + u.d[1].ieee.exponent = exponent2; + else if (exponent2 > -53) lo >>= 1 - exponent2; + else + lo = 0; } else - u.ieee.negative2 = 0; + u.d[1].ieee.negative = 0; - u.ieee.mantissa3 = lo & 0xffffffffLL; - u.ieee.mantissa2 = (lo >> 32) & 0xfffff; - u.ieee.mantissa1 = hi & 0xffffffffLL; - u.ieee.mantissa0 = (hi >> 32) & ((1LL << (LDBL_MANT_DIG - 86)) - 1); + u.d[1].ieee.mantissa1 = lo; + u.d[1].ieee.mantissa0 = lo >> 32; + u.d[0].ieee.mantissa1 = hi; + u.d[0].ieee.mantissa0 = hi >> 32; - return u.d; + return u.ld; } diff --git a/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c b/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c index 247dc20e5a..e0ec422b01 100644 --- a/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c +++ b/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c @@ -26,31 +26,31 @@ do { \ unsigned long long int num0, num1; \ unsigned long long hi, lo; \ int ediff; \ - union ibm_extended_long_double eldbl; \ - eldbl.d = fpnum.ldbl.d; \ + union ibm_extended_long_double u; \ + u.ld = fpnum.ldbl; \ \ assert (sizeof (long double) == 16); \ \ - lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; \ - hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; \ + lo = ((long long)u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1; \ + hi = ((long long)u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1; \ lo <<= 7; /* pre-shift lo to match ieee854. */ \ - /* If the lower double is not a denomal or zero then set the hidden \ + /* If the lower double is not a denormal or zero then set the hidden \ 53rd bit. */ \ - if (eldbl.ieee.exponent2 != 0) \ + if (u.d[1].ieee.exponent != 0) \ lo |= (1ULL << (52 + 7)); \ else \ lo <<= 1; \ /* The lower double is normalized separately from the upper. We \ may need to adjust the lower manitissa to reflect this. */ \ - ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; \ - if (ediff > 53 + 63) \ + ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53; \ + if (ediff > 63) \ lo = 0; \ - else if (ediff > 53) \ - lo = lo >> (ediff - 53); \ - else if (eldbl.ieee.exponent2 == 0 && ediff < 53) \ - lo = lo << (53 - ediff); \ - if (eldbl.ieee.negative != eldbl.ieee.negative2 \ - && (eldbl.ieee.exponent2 != 0 || lo != 0L)) \ + else if (ediff > 0) \ + lo = lo >> ediff; \ + else if (ediff < 0) \ + lo = lo << -ediff; \ + if (u.d[0].ieee.negative != u.d[1].ieee.negative \ + && lo != 0) \ { \ lo = (1ULL << 60) - lo; \ if (hi == 0L) \ @@ -58,7 +58,7 @@ do { \ /* we have a borrow from the hidden bit, so shift left 1. */ \ hi = 0xffffffffffffeLL | (lo >> 59); \ lo = 0xfffffffffffffffLL & (lo << 1); \ - eldbl.ieee.exponent--; \ + u.d[0].ieee.exponent--; \ } \ else \ hi--; \ @@ -109,9 +109,9 @@ do { \ *--wnumstr = L'0'; \ } \ \ - leading = eldbl.ieee.exponent == 0 ? '0' : '1'; \ + leading = u.d[0].ieee.exponent == 0 ? '0' : '1'; \ \ - exponent = eldbl.ieee.exponent; \ + exponent = u.d[0].ieee.exponent; \ \ if (exponent == 0) \ { \ @@ -121,18 +121,18 @@ do { \ { \ /* This is a denormalized number. */ \ expnegative = 1; \ - exponent = IBM_EXTENDED_LONG_DOUBLE_BIAS - 1; \ + exponent = IEEE754_DOUBLE_BIAS - 1; \ } \ } \ - else if (exponent >= IBM_EXTENDED_LONG_DOUBLE_BIAS) \ + else if (exponent >= IEEE754_DOUBLE_BIAS) \ { \ expnegative = 0; \ - exponent -= IBM_EXTENDED_LONG_DOUBLE_BIAS; \ + exponent -= IEEE754_DOUBLE_BIAS; \ } \ else \ { \ expnegative = 1; \ - exponent = -(exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS); \ + exponent = -(exponent - IEEE754_DOUBLE_BIAS); \ } \ } while (0) diff --git a/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c b/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c index a833457eab..63c6edbb1a 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c @@ -38,7 +38,10 @@ long double __asinhl(long double x) { long double t,w; int64_t hx,ix; - GET_LDOUBLE_MSW64(hx,x); + double xhi; + + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); ix = hx&0x7fffffffffffffffLL; if(ix>=0x7ff0000000000000LL) return x+x; /* x is inf or NaN */ if(ix< 0x3e20000000000000LL) { /* |x|<2**-29 */ diff --git a/sysdeps/ieee754/ldbl-128ibm/s_atanl.c b/sysdeps/ieee754/ldbl-128ibm/s_atanl.c index 2a36d16bb4..41dde23998 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_atanl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_atanl.c @@ -173,23 +173,20 @@ static const long double long double __atanl (long double x) { - int k, sign; + int32_t k, sign, lx; long double t, u, p, q; - ieee854_long_double_shape_type s; + double xhi; - s.value = x; - k = s.parts32.w0; - if (k & 0x80000000) - sign = 1; - else - sign = 0; + xhi = ldbl_high (x); + EXTRACT_WORDS (k, lx, xhi); + sign = k & 0x80000000; /* Check for IEEE special cases. */ k &= 0x7fffffff; if (k >= 0x7ff00000) { /* NaN. */ - if ((k & 0xfffff) | s.parts32.w1 ) + if (((k - 0x7ff00000) | lx) != 0) return (x + x); /* Infinity. */ diff --git a/sysdeps/ieee754/ldbl-128ibm/s_cosl.c b/sysdeps/ieee754/ldbl-128ibm/s_cosl.c index 23148392f1..54c6cc77d2 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_cosl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_cosl.c @@ -53,9 +53,11 @@ long double __cosl(long double x) { long double y[2],z=0.0L; int64_t n, ix; + double xhi; /* High word of x. */ - GET_LDOUBLE_MSW64(ix,x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (ix, xhi); /* |x| ~< pi/4 */ ix &= 0x7fffffffffffffffLL; diff --git a/sysdeps/ieee754/ldbl-128ibm/s_erfl.c b/sysdeps/ieee754/ldbl-128ibm/s_erfl.c index 6a4475ed6b..95dc415845 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_erfl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_erfl.c @@ -101,6 +101,7 @@ * erfc/erf(NaN) is NaN */ +#include <errno.h> #include <math.h> #include <math_private.h> #include <math_ldbl_opt.h> @@ -760,16 +761,16 @@ long double __erfl (long double x) { long double a, y, z; - int32_t i, ix, sign; - ieee854_long_double_shape_type u; + int32_t i, ix, hx; + double xhi; - u.value = x; - sign = u.parts32.w0; - ix = sign & 0x7fffffff; + xhi = ldbl_high (x); + GET_HIGH_WORD (hx, xhi); + ix = hx & 0x7fffffff; if (ix >= 0x7ff00000) { /* erf(nan)=nan */ - i = ((sign & 0xfff00000) >> 31) << 1; + i = ((uint32_t) hx >> 31) << 1; return (long double) (1 - i) + one / x; /* erf(+-inf)=+-1 */ } @@ -778,7 +779,7 @@ __erfl (long double x) if (ix >= 0x4039A0DE) { /* __erfcl (x) underflows if x > 25.6283 */ - if (sign) + if ((hx & 0x80000000) == 0) return one-tiny; else return tiny-one; @@ -789,8 +790,9 @@ __erfl (long double x) return (one - y); } } - u.parts32.w0 = ix; - a = u.value; + a = x; + if ((hx & 0x80000000) != 0) + a = -a; z = x * x; if (ix < 0x3fec0000) /* a < 0.875 */ { @@ -814,7 +816,7 @@ __erfl (long double x) y = erf_const + neval (a, TN2, NTN2) / deval (a, TD2, NTD2); } - if (sign & 0x80000000) /* x < 0 */ + if (hx & 0x80000000) /* x < 0 */ y = -y; return( y ); } @@ -824,18 +826,18 @@ long double __erfcl (long double x) { long double y, z, p, r; - int32_t i, ix, sign; - ieee854_long_double_shape_type u; + int32_t i, ix; + uint32_t hx; + double xhi; - u.value = x; - sign = u.parts32.w0; - ix = sign & 0x7fffffff; - u.parts32.w0 = ix; + xhi = ldbl_high (x); + GET_HIGH_WORD (hx, xhi); + ix = hx & 0x7fffffff; if (ix >= 0x7ff00000) { /* erfc(nan)=nan */ /* erfc(+-inf)=0,2 */ - return (long double) (((u_int32_t) sign >> 31) << 1) + one / x; + return (long double) ((hx >> 31) << 1) + one / x; } if (ix < 0x3fd00000) /* |x| <1/4 */ @@ -846,7 +848,8 @@ __erfcl (long double x) } if (ix < 0x3ff40000) /* 1.25 */ { - x = u.value; + if ((hx & 0x80000000) != 0) + x = -x; i = 8.0 * x; switch (i) { @@ -891,7 +894,7 @@ __erfcl (long double x) y += C20a; break; } - if (sign & 0x80000000) + if (hx & 0x80000000) y = 2.0L - y; return y; } @@ -899,10 +902,11 @@ __erfcl (long double x) if (ix < 0x405ac000) { /* x < -9 */ - if ((ix >= 0x40220000) && (sign & 0x80000000)) + if (hx >= 0xc0220000) return two - tiny; - x = fabsl (x); + if ((hx & 0x80000000) != 0) + x = -x; z = one / (x * x); i = 8.0 / x; switch (i) @@ -933,22 +937,26 @@ __erfcl (long double x) p = neval (z, RNr8, NRNr8) / deval (z, RDr8, NRDr8); break; } - u.value = x; - u.parts32.w3 = 0; - u.parts32.w2 = 0; - u.parts32.w1 &= 0xf8000000; - z = u.value; + z = (float) x; r = __ieee754_expl (-z * z - 0.5625) * __ieee754_expl ((z - x) * (z + x) + p); - if ((sign & 0x80000000) == 0) - return r / x; + if ((hx & 0x80000000) == 0) + { + long double ret = r / x; + if (ret == 0) + __set_errno (ERANGE); + return ret; + } else return two - r / x; } else { - if ((sign & 0x80000000) == 0) - return tiny * tiny; + if ((hx & 0x80000000) == 0) + { + __set_errno (ERANGE); + return tiny * tiny; + } else return two - tiny; } diff --git a/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c b/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c index 8808dcd896..007e785346 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c @@ -92,19 +92,19 @@ long double __expm1l (long double x) { long double px, qx, xx; - int32_t ix, sign; - ieee854_long_double_shape_type u; + int32_t ix, lx, sign; int k; + double xhi; /* Detect infinity and NaN. */ - u.value = x; - ix = u.parts32.w0; + xhi = ldbl_high (x); + EXTRACT_WORDS (ix, lx, xhi); sign = ix & 0x80000000; ix &= 0x7fffffff; if (ix >= 0x7ff00000) { /* Infinity. */ - if (((ix & 0xfffff) | u.parts32.w1 | (u.parts32.w2&0x7fffffff) | u.parts32.w3) == 0) + if (((ix - 0x7ff00000) | lx) == 0) { if (sign) return -1.0L; @@ -116,7 +116,7 @@ __expm1l (long double x) } /* expm1(+- 0) = +- 0. */ - if ((ix == 0) && (u.parts32.w1 | (u.parts32.w2&0x7fffffff) | u.parts32.w3) == 0) + if ((ix | lx) == 0) return x; /* Overflow. */ diff --git a/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c b/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c index 99146d8021..c801c97065 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c @@ -29,10 +29,16 @@ static char rcsid[] = "$NetBSD: $"; long double __fabsl(long double x) { u_int64_t hx, lx; - GET_LDOUBLE_WORDS64(hx,lx,x); + double xhi, xlo; + + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS64 (hx, xhi); + EXTRACT_WORDS64 (lx, xlo); lx = lx ^ ( hx & 0x8000000000000000LL ); hx = hx & 0x7fffffffffffffffLL; - SET_LDOUBLE_WORDS64(x,hx,lx); + INSERT_WORDS64 (xhi, hx); + INSERT_WORDS64 (xlo, lx); + x = ldbl_pack (xhi, xlo); return x; } long_double_symbol (libm, __fabsl, fabsl); diff --git a/sysdeps/ieee754/ldbl-128ibm/s_finitel.c b/sysdeps/ieee754/ldbl-128ibm/s_finitel.c index 8edb34154d..7b4655fadb 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_finitel.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_finitel.c @@ -29,10 +29,14 @@ static char rcsid[] = "$NetBSD: $"; int ___finitel (long double x) { - int64_t hx; - GET_LDOUBLE_MSW64(hx,x); - return (int)((u_int64_t)((hx&0x7fffffffffffffffLL) - -0x7ff0000000000000LL)>>63); + uint64_t hx; + double xhi; + + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); + hx &= 0x7fffffffffffffffLL; + hx -= 0x7ff0000000000000LL; + return hx >> 63; } hidden_ver (___finitel, __finitel) weak_alias (___finitel, ____finitel) diff --git a/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c b/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c index f4a90b08c7..90586e822e 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c @@ -46,8 +46,10 @@ ___fpclassifyl (long double x) { u_int64_t hx, lx; int retval = FP_NORMAL; + double xhi, xlo; - GET_LDOUBLE_WORDS64 (hx, lx, x); + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS64 (hx, xhi); if ((hx & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL) { /* +/-NaN or +/-Inf */ if (hx & 0x000fffffffffffffULL) { @@ -65,6 +67,7 @@ ___fpclassifyl (long double x) retval = FP_NORMAL; } else { if ((hx & 0x7ff0000000000000ULL) == 0x0360000000000000ULL) { + EXTRACT_WORDS64 (lx, xlo); if ((lx & 0x7fffffffffffffff) /* lower is non-zero */ && ((lx^hx) & 0x8000000000000000ULL)) { /* and sign differs */ /* +/- denormal */ diff --git a/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c b/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c index 3ac5374116..7e40663fd4 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c @@ -36,16 +36,21 @@ two107 = 162259276829213363391578010288128.0; /* 0x4670000000000000, 0 */ long double __frexpl(long double x, int *eptr) { - u_int64_t hx, lx, ix, ixl; + uint64_t hx, lx, ix, ixl; int64_t explo; - GET_LDOUBLE_WORDS64(hx,lx,x); + double xhi, xlo; + + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS64 (hx, xhi); + EXTRACT_WORDS64 (lx, xlo); ixl = 0x7fffffffffffffffULL&lx; ix = 0x7fffffffffffffffULL&hx; *eptr = 0; - if(ix>=0x7ff0000000000000ULL||((ix|ixl)==0)) return x; /* 0,inf,nan */ + if(ix>=0x7ff0000000000000ULL||ix==0) return x; /* 0,inf,nan */ if (ix<0x0010000000000000ULL) { /* subnormal */ x *= two107; - GET_LDOUBLE_MSW64(hx,x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); ix = hx&0x7fffffffffffffffULL; *eptr = -107; } @@ -54,7 +59,7 @@ long double __frexpl(long double x, int *eptr) if (ixl != 0ULL) { explo = (ixl>>52) - (ix>>52) + 0x3fe; if ((ixl&0x7ff0000000000000ULL) == 0LL) { - /* the lower double is a denomal so we need to correct its + /* the lower double is a denormal so we need to correct its mantissa and perhaps its exponent. */ int cnt; @@ -73,7 +78,9 @@ long double __frexpl(long double x, int *eptr) lx = 0ULL; hx = (hx&0x800fffffffffffffULL) | 0x3fe0000000000000ULL; - SET_LDOUBLE_WORDS64(x,hx,lx); + INSERT_WORDS64 (xhi, hx); + INSERT_WORDS64 (xlo, lx); + x = ldbl_pack (xhi, xlo); return x; } #ifdef IS_IN_libm diff --git a/sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c b/sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c index c8dd9ff98a..54e72c9166 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c @@ -1,6 +1,7 @@ /* * __isinf_nsl(x) returns != 0 if x is ±inf, else 0; * no branching! + * slightly dodgy in relying on signed shift right copying sign bit */ #include <math.h> @@ -9,8 +10,14 @@ int __isinf_nsl (long double x) { - int64_t hx,lx; - GET_LDOUBLE_WORDS64(hx,lx,x); - return !((lx & 0x7fffffffffffffffLL) - | ((hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL)); + double xhi; + int64_t hx, mask; + + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); + + mask = (hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL; + mask |= -mask; + mask >>= 63; + return ~mask; } diff --git a/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c b/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c index 5f5b0144b2..6a728221fc 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c @@ -11,6 +11,7 @@ static char rcsid[] = "$NetBSD: $"; /* * isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0; * no branching! + * slightly dodgy in relying on signed shift right copying sign bit */ #include <math.h> @@ -20,12 +21,16 @@ static char rcsid[] = "$NetBSD: $"; int ___isinfl (long double x) { - int64_t hx,lx; - GET_LDOUBLE_WORDS64(hx,lx,x); - lx = (lx & 0x7fffffffffffffffLL); - lx |= (hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL; - lx |= -lx; - return ~(lx >> 63) & (hx >> 62); + double xhi; + int64_t hx, mask; + + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); + + mask = (hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL; + mask |= -mask; + mask >>= 63; + return ~mask & (hx >> 62); } hidden_ver (___isinfl, __isinfl) #ifndef IS_IN_libm diff --git a/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c b/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c index 264dec745e..d12f1d3bf5 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c @@ -29,12 +29,14 @@ static char rcsid[] = "$NetBSD: $"; int ___isnanl (long double x) { - int64_t hx; - int64_t lx __attribute__ ((unused)); - GET_LDOUBLE_WORDS64(hx,lx,x); - hx &= 0x7fffffffffffffffLL; - hx = 0x7ff0000000000000LL - hx; - return (int)((u_int64_t)hx>>63); + uint64_t hx; + double xhi; + + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); + hx &= 0x7fffffffffffffffLL; + hx = 0x7ff0000000000000LL - hx; + return (int) (hx >> 63); } hidden_ver (___isnanl, __isnanl) #ifndef IS_IN_libm diff --git a/sysdeps/ieee754/ldbl-128ibm/s_issignalingl.c b/sysdeps/ieee754/ldbl-128ibm/s_issignalingl.c index 96fab1aff1..bdd58f8f25 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_issignalingl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_issignalingl.c @@ -22,10 +22,13 @@ int __issignalingl (long double x) { - u_int64_t xi; + uint64_t xi; /* For inspecting NaN status, we only have to look at the first of the pair of IEEE 754 64-bit precision numbers. */ - GET_LDOUBLE_MSW64 (xi, x); + double xhi; + + xhi = ldbl_high (x); + EXTRACT_WORDS64 (xi, xhi); #ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN # error untested /* We only have to care about the high-order bit of x's significand, because diff --git a/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c b/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c index 8560349631..35039737bf 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c @@ -43,7 +43,7 @@ __llrintl (long double x) #endif ) { - save_round = fegetround (); + save_round = __fegetround (); if (__builtin_expect ((xh == -(double) (-__LONG_LONG_MAX__ - 1)), 0)) { diff --git a/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c b/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c index 77c4fdea84..a346383052 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c @@ -126,19 +126,18 @@ long double __log1pl (long double xm1) { long double x, y, z, r, s; - ieee854_long_double_shape_type u; - int32_t hx; + double xhi; + int32_t hx, lx; int e; /* Test for NaN or infinity input. */ - u.value = xm1; - hx = u.parts32.w0; + xhi = ldbl_high (xm1); + EXTRACT_WORDS (hx, lx, xhi); if (hx >= 0x7ff00000) return xm1; /* log1p(+- 0) = +- 0. */ - if (((hx & 0x7fffffff) == 0) - && (u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) == 0) + if (((hx & 0x7fffffff) | lx) == 0) return xm1; x = xm1 + 1.0L; diff --git a/sysdeps/ieee754/ldbl-128ibm/s_logbl.c b/sysdeps/ieee754/ldbl-128ibm/s_logbl.c index 6cbfcfa1cc..da8d71bdec 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_logbl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_logbl.c @@ -27,9 +27,10 @@ long double __logbl (long double x) { int64_t hx, rhx; - int64_t lx __attribute__ ((unused)); + double xhi; - GET_LDOUBLE_WORDS64 (hx, lx, x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (hx, xhi); hx &= 0x7fffffffffffffffLL; /* high |x| */ if (hx == 0) return -1.0 / fabs (x); @@ -43,5 +44,6 @@ __logbl (long double x) } return (long double) (rhx - 1023); } - +#ifndef __logbl long_double_symbol (libm, __logbl, logbl); +#endif diff --git a/sysdeps/ieee754/ldbl-128ibm/s_lrintl.c b/sysdeps/ieee754/ldbl-128ibm/s_lrintl.c index 588098d090..49dbd42f5b 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_lrintl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_lrintl.c @@ -49,7 +49,7 @@ __lrintl (long double x) #endif ) { - save_round = fegetround (); + save_round = __fegetround (); #if __LONG_MAX__ == 2147483647 long long llhi = (long long) xh; diff --git a/sysdeps/ieee754/ldbl-128ibm/s_modfl.c b/sysdeps/ieee754/ldbl-128ibm/s_modfl.c index 39de9d4bfb..ed03ce236c 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_modfl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_modfl.c @@ -37,43 +37,54 @@ long double __modfl(long double x, long double *iptr) { int64_t i0,i1,j0; u_int64_t i; - GET_LDOUBLE_WORDS64(i0,i1,x); + double xhi, xlo; + + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS64 (i0, xhi); + EXTRACT_WORDS64 (i1, xlo); i1 &= 0x000fffffffffffffLL; j0 = ((i0>>52)&0x7ff)-0x3ff; /* exponent of x */ if(j0<52) { /* integer part in high x */ if(j0<0) { /* |x|<1 */ /* *iptr = +-0 */ - SET_LDOUBLE_WORDS64(*iptr,i0&0x8000000000000000ULL,0); + INSERT_WORDS64 (xhi, i0&0x8000000000000000ULL); + *iptr = xhi; return x; } else { i = (0x000fffffffffffffLL)>>j0; if(((i0&i)|(i1&0x7fffffffffffffffLL))==0) { /* x is integral */ *iptr = x; /* return +-0 */ - SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0); + INSERT_WORDS64 (xhi, i0&0x8000000000000000ULL); + x = xhi; return x; } else { - SET_LDOUBLE_WORDS64(*iptr,i0&(~i),0); + INSERT_WORDS64 (xhi, i0&(~i)); + *iptr = xhi; return x - *iptr; } } } else if (j0>103) { /* no fraction part */ *iptr = x*one; /* We must handle NaNs separately. */ - if (j0 == 0x400 && ((i0 & 0x000fffffffffffffLL) | i1)) + if ((i0 & 0x7fffffffffffffffLL) > 0x7ff0000000000000LL) return x*one; /* return +-0 */ - SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0); + INSERT_WORDS64 (xhi, i0&0x8000000000000000ULL); + x = xhi; return x; } else { /* fraction part in low x */ i = -1ULL>>(j0-52); if((i1&i)==0) { /* x is integral */ *iptr = x; /* return +-0 */ - SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0); + INSERT_WORDS64 (xhi, i0&0x8000000000000000ULL); + x = xhi; return x; } else { - SET_LDOUBLE_WORDS64(*iptr,i0,i1&(~i)); + INSERT_WORDS64 (xhi, i0); + INSERT_WORDS64 (xlo, i1&(~i)); + *iptr = ldbl_pack (xhi, xlo); return x - *iptr; } } diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c b/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c index bfcd11044d..92ced5218b 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c @@ -34,11 +34,11 @@ __nearbyintl (long double x) fenv_t env; static const long double TWO52 = 4503599627370496.0L; union ibm_extended_long_double u; - u.d = x; + u.ld = x; - if (fabs (u.dd[0]) < TWO52) + if (fabs (u.d[0].d) < TWO52) { - double high = u.dd[0]; + double high = u.d[0].d; feholdexcept (&env); if (high > 0.0) { @@ -52,13 +52,13 @@ __nearbyintl (long double x) high += TWO52; if (high == 0.0) high = -0.0; } - u.dd[0] = high; - u.dd[1] = 0.0; - math_force_eval (u.dd[0]); - math_force_eval (u.dd[1]); + u.d[0].d = high; + u.d[1].d = 0.0; + math_force_eval (u.d[0]); + math_force_eval (u.d[1]); fesetenv (&env); } - else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0) + else if (fabs (u.d[1].d) < TWO52 && u.d[1].d != 0.0) { double high, low, tau; /* In this case we have to round the low double and handle any @@ -67,57 +67,57 @@ __nearbyintl (long double x) may already be rounded and the low double may have the opposite sign to compensate. */ feholdexcept (&env); - if (u.dd[0] > 0.0) + if (u.d[0].d > 0.0) { - if (u.dd[1] > 0.0) + if (u.d[1].d > 0.0) { /* If the high/low doubles are the same sign then simply round the low double. */ - high = u.dd[0]; - low = u.dd[1]; + high = u.d[0].d; + low = u.d[1].d; } - else if (u.dd[1] < 0.0) + else if (u.d[1].d < 0.0) { /* Else the high double is pre rounded and we need to adjust for that. */ - tau = __nextafter (u.dd[0], 0.0); - tau = (u.dd[0] - tau) * 2.0; - high = u.dd[0] - tau; - low = u.dd[1] + tau; + tau = __nextafter (u.d[0].d, 0.0); + tau = (u.d[0].d - tau) * 2.0; + high = u.d[0].d - tau; + low = u.d[1].d + tau; } low += TWO52; low -= TWO52; } - else if (u.dd[0] < 0.0) + else if (u.d[0].d < 0.0) { - if (u.dd[1] < 0.0) + if (u.d[1].d < 0.0) { /* If the high/low doubles are the same sign then simply round the low double. */ - high = u.dd[0]; - low = u.dd[1]; + high = u.d[0].d; + low = u.d[1].d; } - else if (u.dd[1] > 0.0) + else if (u.d[1].d > 0.0) { /* Else the high double is pre rounded and we need to adjust for that. */ - tau = __nextafter (u.dd[0], 0.0); - tau = (u.dd[0] - tau) * 2.0; - high = u.dd[0] - tau; - low = u.dd[1] + tau; + tau = __nextafter (u.d[0].d, 0.0); + tau = (u.d[0].d - tau) * 2.0; + high = u.d[0].d - tau; + low = u.d[1].d + tau; } low = TWO52 - low; low = -(low - TWO52); } - u.dd[0] = high + low; - u.dd[1] = high - u.dd[0] + low; - math_force_eval (u.dd[0]); - math_force_eval (u.dd[1]); + u.d[0].d = high + low; + u.d[1].d = high - u.d[0].d + low; + math_force_eval (u.d[0]); + math_force_eval (u.d[1]); fesetenv (&env); } - return u.d; + return u.ld; } long_double_symbol (libm, __nearbyintl, nearbyintl); diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c b/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c index 7e581274a3..c050944c0c 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c @@ -30,27 +30,28 @@ static char rcsid[] = "$NetBSD: $"; long double __nextafterl(long double x, long double y) { - int64_t hx,hy,ihx,ihy,ilx; - u_int64_t lx; - u_int64_t ly __attribute__ ((unused)); + int64_t hx,hy,ihx,ihy; + uint64_t lx; + double xhi, xlo, yhi; - GET_LDOUBLE_WORDS64(hx,lx,x); - GET_LDOUBLE_WORDS64(hy,ly,y); + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS64 (hx, xhi); + EXTRACT_WORDS64 (lx, xlo); + yhi = ldbl_high (y); + EXTRACT_WORDS64 (hy, yhi); ihx = hx&0x7fffffffffffffffLL; /* |hx| */ - ilx = lx&0x7fffffffffffffffLL; /* |lx| */ ihy = hy&0x7fffffffffffffffLL; /* |hy| */ - if((((ihx&0x7ff0000000000000LL)==0x7ff0000000000000LL)&& - ((ihx&0x000fffffffffffffLL)!=0)) || /* x is nan */ - (((ihy&0x7ff0000000000000LL)==0x7ff0000000000000LL)&& - ((ihy&0x000fffffffffffffLL)!=0))) /* y is nan */ + if((ihx>0x7ff0000000000000LL) || /* x is nan */ + (ihy>0x7ff0000000000000LL)) /* y is nan */ return x+y; /* signal the nan */ if(x==y) return y; /* x=y, return y */ - if(ihx == 0 && ilx == 0) { /* x == 0 */ - long double u; + if(ihx == 0) { /* x == 0 */ + long double u; /* return +-minsubnormal */ hy = (hy & 0x8000000000000000ULL) | 1; - SET_LDOUBLE_WORDS64(x,hy,0ULL);/* return +-minsubnormal */ + INSERT_WORDS64 (yhi, hy); + x = yhi; u = math_opt_barrier (x); u = u * u; math_force_eval (u); /* raise underflow flag */ @@ -59,10 +60,16 @@ long double __nextafterl(long double x, long double y) long double u; if(x > y) { /* x > y, x -= ulp */ + /* This isn't the largest magnitude correctly rounded + long double as you can see from the lowest mantissa + bit being zero. It is however the largest magnitude + long double with a 106 bit mantissa, and nextafterl + is insane with variable precision. So to make + nextafterl sane we assume 106 bit precision. */ if((hx==0xffefffffffffffffLL)&&(lx==0xfc8ffffffffffffeLL)) return x+x; /* overflow, return -inf */ if (hx >= 0x7ff0000000000000LL) { - SET_LDOUBLE_WORDS64(u,0x7fefffffffffffffLL,0x7c8ffffffffffffeLL); + u = 0x1.fffffffffffff7ffffffffffff8p+1023L; return u; } if(ihx <= 0x0360000000000000LL) { /* x <= LDBL_MIN */ @@ -77,16 +84,19 @@ long double __nextafterl(long double x, long double y) return x; } if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */ - SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL); + INSERT_WORDS64 (yhi, hx & (0x7ffLL<<52)); + u = yhi; u *= 0x1.0000000000000p-105L; - } else - SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL); + } else { + INSERT_WORDS64 (yhi, (hx & (0x7ffLL<<52))-(0x069LL<<52)); + u = yhi; + } return x - u; } else { /* x < y, x += ulp */ if((hx==0x7fefffffffffffffLL)&&(lx==0x7c8ffffffffffffeLL)) return x+x; /* overflow, return +inf */ - if ((u_int64_t) hx >= 0xfff0000000000000ULL) { - SET_LDOUBLE_WORDS64(u,0xffefffffffffffffLL,0xfc8ffffffffffffeLL); + if ((uint64_t) hx >= 0xfff0000000000000ULL) { + u = -0x1.fffffffffffff7ffffffffffff8p+1023L; return u; } if(ihx <= 0x0360000000000000LL) { /* x <= LDBL_MIN */ @@ -103,10 +113,13 @@ long double __nextafterl(long double x, long double y) return x; } if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */ - SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL); + INSERT_WORDS64 (yhi, hx & (0x7ffLL<<52)); + u = yhi; u *= 0x1.0000000000000p-105L; - } else - SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL); + } else { + INSERT_WORDS64 (yhi, (hx & (0x7ffLL<<52))-(0x069LL<<52)); + u = yhi; + } return x + u; } } diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c b/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c index 7e288a4368..b40cf167f3 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c @@ -34,23 +34,22 @@ double __nexttoward(double x, long double y) { int32_t hx,ix; int64_t hy,iy; - u_int32_t lx; - u_int64_t ly,uly; + uint32_t lx; + double yhi; EXTRACT_WORDS(hx,lx,x); - GET_LDOUBLE_WORDS64(hy,ly,y); + yhi = ldbl_high (y); + EXTRACT_WORDS64(hy,yhi); ix = hx&0x7fffffff; /* |x| */ iy = hy&0x7fffffffffffffffLL; /* |y| */ - uly = ly&0x7fffffffffffffffLL; /* |y| */ if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ - ((iy>=0x7ff0000000000000LL)&&((iy-0x7ff0000000000000LL)|uly)!=0)) - /* y is nan */ + iy>0x7ff0000000000000LL) /* y is nan */ return x+y; if((long double) x==y) return y; /* x=y, return y */ if((ix|lx)==0) { /* x == 0 */ double u; - INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */ + INSERT_WORDS(x,(uint32_t)((hy>>32)&0x80000000),1);/* return +-minsub */ u = math_opt_barrier (x); u = u * u; math_force_eval (u); /* raise underflow flag */ diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c b/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c index b387a91192..19522f4762 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c @@ -27,16 +27,16 @@ float __nexttowardf(float x, long double y) { int32_t hx,ix; int64_t hy,iy; - u_int64_t ly, uly; + double yhi; GET_FLOAT_WORD(hx,x); - GET_LDOUBLE_WORDS64(hy,ly,y); + yhi = ldbl_high (y); + EXTRACT_WORDS64 (hy, yhi); ix = hx&0x7fffffff; /* |x| */ iy = hy&0x7fffffffffffffffLL; /* |y| */ - uly = ly&0x7fffffffffffffffLL; /* |y| */ if((ix>0x7f800000) || /* x is nan */ - ((iy>=0x7ff0000000000000LL)&&((iy-0x7ff0000000000000LL)|uly)!=0)) + (iy>0x7ff0000000000000LL)) /* y is nan */ return x+y; if((long double) x==y) return y; /* x=y, return y */ diff --git a/sysdeps/ieee754/ldbl-128ibm/s_remquol.c b/sysdeps/ieee754/ldbl-128ibm/s_remquol.c index f4777a0e1a..195e108ca9 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_remquol.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_remquol.c @@ -33,20 +33,24 @@ __remquol (long double x, long double y, int *quo) int64_t hx,hy; u_int64_t sx,lx,ly,qs; int cquo; - - GET_LDOUBLE_WORDS64 (hx, lx, x); - GET_LDOUBLE_WORDS64 (hy, ly, y); + double xhi, xlo, yhi, ylo; + + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS64 (hx, xhi); + EXTRACT_WORDS64 (lx, xlo); + ldbl_unpack (y, &yhi, &ylo); + EXTRACT_WORDS64 (hy, yhi); + EXTRACT_WORDS64 (ly, ylo); sx = hx & 0x8000000000000000ULL; qs = sx ^ (hy & 0x8000000000000000ULL); hy &= 0x7fffffffffffffffLL; hx &= 0x7fffffffffffffffLL; /* Purge off exception values. */ - if ((hy | (ly & 0x7fffffffffffffff)) == 0) + if (hy == 0) return (x * y) / (x * y); /* y = 0 */ if ((hx >= 0x7ff0000000000000LL) /* x not finite */ - || ((hy >= 0x7ff0000000000000LL) /* y is NaN */ - && (((hy - 0x7ff0000000000000LL) | ly) != 0))) + || (hy > 0x7ff0000000000000LL)) /* y is NaN */ return (x * y) / (x * y); if (hy <= 0x7fbfffffffffffffLL) diff --git a/sysdeps/ieee754/ldbl-128ibm/s_rintl.c b/sysdeps/ieee754/ldbl-128ibm/s_rintl.c index 48dbe8569c..5fd6bb8702 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_rintl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_rintl.c @@ -40,7 +40,7 @@ __rintl (long double x) __builtin_inf ()), 1)) { double orig_xh; - int save_round = fegetround (); + int save_round = __fegetround (); /* Long double arithmetic, including the canonicalisation below, only works in round-to-nearest mode. */ diff --git a/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c b/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c index d752568885..03d4597271 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c @@ -41,11 +41,15 @@ long double __scalblnl (long double x, long int n) { int64_t k,l,hx,lx; union { int64_t i; double d; } u; - GET_LDOUBLE_WORDS64(hx,lx,x); + double xhi, xlo; + + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS64 (hx, xhi); + EXTRACT_WORDS64 (lx, xlo); k = (hx>>52)&0x7ff; /* extract exponent */ l = (lx>>52)&0x7ff; if (k==0) { /* 0 or subnormal x */ - if (((hx|lx)&0x7fffffffffffffffULL)==0) return x; /* +-0 */ + if ((hx&0x7fffffffffffffffULL)==0) return x; /* +-0 */ u.i = hx; u.d *= two54; hx = u.i; @@ -61,7 +65,9 @@ long double __scalblnl (long double x, long int n) if (k > 0) { /* normal result */ hx = (hx&0x800fffffffffffffULL)|(k<<52); if ((lx & 0x7fffffffffffffffULL) == 0) { /* low part +-0 */ - SET_LDOUBLE_WORDS64(x,hx,lx); + INSERT_WORDS64 (xhi, hx); + INSERT_WORDS64 (xlo, lx); + x = ldbl_pack (xhi, xlo); return x; } if (l == 0) { /* low part subnormal */ @@ -81,14 +87,19 @@ long double __scalblnl (long double x, long int n) u.d *= twom54; lx = u.i; } - SET_LDOUBLE_WORDS64(x,hx,lx); + INSERT_WORDS64 (xhi, hx); + INSERT_WORDS64 (xlo, lx); + x = ldbl_pack (xhi, xlo); return x; } if (k <= -54) return tiny*__copysignl(tiny,x); /*underflow*/ k += 54; /* subnormal result */ lx &= 0x8000000000000000ULL; - SET_LDOUBLE_WORDS64(x,(hx&0x800fffffffffffffULL)|(k<<52),lx); + hx &= 0x800fffffffffffffULL; + INSERT_WORDS64 (xhi, hx|(k<<52)); + INSERT_WORDS64 (xlo, lx); + x = ldbl_pack (xhi, xlo); return x*twolm54; } long_double_symbol (libm, __scalblnl, scalblnl); diff --git a/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c b/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c index bcdb23bdaa..161172db6e 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c @@ -41,11 +41,15 @@ long double __scalbnl (long double x, int n) { int64_t k,l,hx,lx; union { int64_t i; double d; } u; - GET_LDOUBLE_WORDS64(hx,lx,x); + double xhi, xlo; + + ldbl_unpack (x, &xhi, &xlo); + EXTRACT_WORDS64 (hx, xhi); + EXTRACT_WORDS64 (lx, xlo); k = (hx>>52)&0x7ff; /* extract exponent */ l = (lx>>52)&0x7ff; if (k==0) { /* 0 or subnormal x */ - if (((hx|lx)&0x7fffffffffffffffULL)==0) return x; /* +-0 */ + if ((hx&0x7fffffffffffffffULL)==0) return x; /* +-0 */ u.i = hx; u.d *= two54; hx = u.i; @@ -61,7 +65,9 @@ long double __scalbnl (long double x, int n) if (k > 0) { /* normal result */ hx = (hx&0x800fffffffffffffULL)|(k<<52); if ((lx & 0x7fffffffffffffffULL) == 0) { /* low part +-0 */ - SET_LDOUBLE_WORDS64(x,hx,lx); + INSERT_WORDS64 (xhi, hx); + INSERT_WORDS64 (xlo, lx); + x = ldbl_pack (xhi, xlo); return x; } if (l == 0) { /* low part subnormal */ @@ -81,14 +87,19 @@ long double __scalbnl (long double x, int n) u.d *= twom54; lx = u.i; } - SET_LDOUBLE_WORDS64(x,hx,lx); + INSERT_WORDS64 (xhi, hx); + INSERT_WORDS64 (xlo, lx); + x = ldbl_pack (xhi, xlo); return x; } if (k <= -54) return tiny*__copysignl(tiny,x); /*underflow*/ k += 54; /* subnormal result */ lx &= 0x8000000000000000ULL; - SET_LDOUBLE_WORDS64(x,(hx&0x800fffffffffffffULL)|(k<<52),lx); + hx &= 0x800fffffffffffffULL; + INSERT_WORDS64 (xhi, hx|(k<<52)); + INSERT_WORDS64 (xlo, lx); + x = ldbl_pack (xhi, xlo); return x*twolm54; } #ifdef IS_IN_libm diff --git a/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c b/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c index ee4aea6cf4..aecb1fd792 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c @@ -25,8 +25,10 @@ int ___signbitl (long double x) { int64_t e; + double xhi; - GET_LDOUBLE_MSW64 (e, x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (e, xhi); return e < 0; } #ifdef IS_IN_libm diff --git a/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c b/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c index 3b1e547bdc..a9e2f3d19a 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c @@ -27,9 +27,11 @@ void __sincosl (long double x, long double *sinx, long double *cosx) { int64_t ix; + double xhi; /* High word of x. */ - GET_LDOUBLE_MSW64 (ix, x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (ix, xhi); /* |x| ~< pi/4 */ ix &= 0x7fffffffffffffffLL; diff --git a/sysdeps/ieee754/ldbl-128ibm/s_sinl.c b/sysdeps/ieee754/ldbl-128ibm/s_sinl.c index 6fec16f851..087921a913 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_sinl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_sinl.c @@ -53,9 +53,11 @@ long double __sinl(long double x) { long double y[2],z=0.0L; int64_t n, ix; + double xhi; /* High word of x. */ - GET_LDOUBLE_MSW64(ix,x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (ix, xhi); /* |x| ~< pi/4 */ ix &= 0x7fffffffffffffffLL; diff --git a/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c b/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c index 138b63cd1a..c63e25345d 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c @@ -47,10 +47,12 @@ static const long double one=1.0L, two=2.0L, tiny = 1.0e-300L; long double __tanhl(long double x) { long double t,z; - int64_t jx,ix,lx; + int64_t jx,ix; + double xhi; /* High word of |x|. */ - GET_LDOUBLE_WORDS64(jx,lx,x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (jx, xhi); ix = jx&0x7fffffffffffffffLL; /* x is INF or NaN */ @@ -61,7 +63,7 @@ long double __tanhl(long double x) /* |x| < 22 */ if (ix < 0x4036000000000000LL) { /* |x|<22 */ - if ((ix | (lx&0x7fffffffffffffffLL)) == 0) + if (ix == 0) return x; /* x == +-0 */ if (ix<0x3c60000000000000LL) /* |x|<2**-57 */ return x*(one+x); /* tanh(small) = small */ diff --git a/sysdeps/ieee754/ldbl-128ibm/s_tanl.c b/sysdeps/ieee754/ldbl-128ibm/s_tanl.c index 9967d0c206..66b8a0621e 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_tanl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_tanl.c @@ -53,9 +53,11 @@ long double __tanl(long double x) { long double y[2],z=0.0L; int64_t n, ix; + double xhi; /* High word of x. */ - GET_LDOUBLE_MSW64(ix,x); + xhi = ldbl_high (x); + EXTRACT_WORDS64 (ix, xhi); /* |x| ~< pi/4 */ ix &= 0x7fffffffffffffffLL; diff --git a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c index 04e3288571..93a80c5eec 100644 --- a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c +++ b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c @@ -43,11 +43,11 @@ libc_hidden_proto (STRTOF) #define FLOAT_HUGE_VAL HUGE_VALL # define SET_MANTISSA(flt, mant) \ do { union ibm_extended_long_double u; \ - u.d = (flt); \ - u.ieee_nan.mantissa0 = (mant) >> 32; \ - u.ieee_nan.mantissa1 = (mant); \ - if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \ - (flt) = u.d; \ + u.ld = (flt); \ + u.d[0].ieee_nan.mantissa0 = (mant) >> 32; \ + u.d[0].ieee_nan.mantissa1 = (mant); \ + if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0) \ + (flt) = u.ld; \ } while (0) #include <strtod_l.c> diff --git a/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c b/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c index ed0d4a5067..06dcf02ffe 100644 --- a/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c +++ b/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c @@ -89,23 +89,23 @@ __x2y2m1l (long double x, long double y) double vals[12]; SET_RESTORE_ROUND (FE_TONEAREST); union ibm_extended_long_double xu, yu; - xu.d = x; - yu.d = y; - if (fabs (xu.dd[1]) < 0x1p-500) - xu.dd[1] = 0.0; - if (fabs (yu.dd[1]) < 0x1p-500) - yu.dd[1] = 0.0; - mul_split (&vals[1], &vals[0], xu.dd[0], xu.dd[0]); - mul_split (&vals[3], &vals[2], xu.dd[0], xu.dd[1]); + xu.ld = x; + yu.ld = y; + if (fabs (xu.d[1].d) < 0x1p-500) + xu.d[1].d = 0.0; + if (fabs (yu.d[1].d) < 0x1p-500) + yu.d[1].d = 0.0; + mul_split (&vals[1], &vals[0], xu.d[0].d, xu.d[0].d); + mul_split (&vals[3], &vals[2], xu.d[0].d, xu.d[1].d); vals[2] *= 2.0; vals[3] *= 2.0; - mul_split (&vals[5], &vals[4], xu.dd[1], xu.dd[1]); - mul_split (&vals[7], &vals[6], yu.dd[0], yu.dd[0]); - mul_split (&vals[9], &vals[8], yu.dd[0], yu.dd[1]); + mul_split (&vals[5], &vals[4], xu.d[1].d, xu.d[1].d); + mul_split (&vals[7], &vals[6], yu.d[0].d, yu.d[0].d); + mul_split (&vals[9], &vals[8], yu.d[0].d, yu.d[1].d); vals[8] *= 2.0; vals[9] *= 2.0; - mul_split (&vals[11], &vals[10], yu.dd[1], yu.dd[1]); - if (xu.dd[0] >= 0.75) + mul_split (&vals[11], &vals[10], yu.d[1].d, yu.d[1].d); + if (xu.d[0].d >= 0.75) vals[1] -= 1.0; else { diff --git a/sysdeps/ieee754/ldbl-96/e_atan2l.c b/sysdeps/ieee754/ldbl-96/e_atan2l.c deleted file mode 100644 index 209f29bbd2..0000000000 --- a/sysdeps/ieee754/ldbl-96/e_atan2l.c +++ /dev/null @@ -1,125 +0,0 @@ -/* e_atan2l.c -- long double version of e_atan2.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -/* __ieee754_atan2l(y,x) - * Method : - * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). - * 2. Reduce x to positive by (if x and y are unexceptional): - * ARG (x+iy) = arctan(y/x) ... if x > 0, - * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, - * - * Special cases: - * - * ATAN2((anything), NaN ) is NaN; - * ATAN2(NAN , (anything) ) is NaN; - * ATAN2(+-0, +(anything but NaN)) is +-0 ; - * ATAN2(+-0, -(anything but NaN)) is +-pi ; - * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; - * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; - * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; - * ATAN2(+-INF,+INF ) is +-pi/4 ; - * ATAN2(+-INF,-INF ) is +-3pi/4; - * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; - * - * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - -#include <math.h> -#include <math_private.h> - -static const long double -tiny = 1.0e-4900L, -zero = 0.0, -pi_o_4 = 7.85398163397448309628202E-01L, /* 0x3FFE, 0xC90FDAA2, 0x2168C235 */ -pi_o_2 = 1.5707963267948966192564E+00L, /* 0x3FFF, 0xC90FDAA2, 0x2168C235 */ -pi = 3.14159265358979323851281E+00L, /* 0x4000, 0xC90FDAA2, 0x2168C235 */ -pi_lo = -5.01655761266833202345176e-20L;/* 0xBFBE, 0xECE675D1, 0xFC8F8CBB */ - -long double -__ieee754_atan2l (long double y, long double x) -{ - long double z; - int32_t k,m,hx,hy,ix,iy; - u_int32_t sx,sy,lx,ly; - - GET_LDOUBLE_WORDS(sx,hx,lx,x); - ix = sx&0x7fff; - lx |= hx & 0x7fffffff; - GET_LDOUBLE_WORDS(sy,hy,ly,y); - iy = sy&0x7fff; - ly |= hy & 0x7fffffff; - if(((2*ix|((lx|-lx)>>31))>0xfffe)|| - ((2*iy|((ly|-ly)>>31))>0xfffe)) /* x or y is NaN */ - return x+y; - if(((sx-0x3fff)|lx)==0) return __atanl(y); /* x=1.0 */ - m = ((sy>>15)&1)|((sx>>14)&2); /* 2*sign(x)+sign(y) */ - - /* when y = 0 */ - if((iy|ly)==0) { - switch(m) { - case 0: - case 1: return y; /* atan(+-0,+anything)=+-0 */ - case 2: return pi+tiny;/* atan(+0,-anything) = pi */ - case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ - } - } - /* when x = 0 */ - if((ix|lx)==0) return (sy>=0x8000)? -pi_o_2-tiny: pi_o_2+tiny; - - /* when x is INF */ - if(ix==0x7fff) { - if(iy==0x7fff) { - switch(m) { - case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ - case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ - case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ - case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ - } - } else { - switch(m) { - case 0: return zero ; /* atan(+...,+INF) */ - case 1: return -zero ; /* atan(-...,+INF) */ - case 2: return pi+tiny ; /* atan(+...,-INF) */ - case 3: return -pi-tiny ; /* atan(-...,-INF) */ - } - } - } - /* when y is INF */ - if(iy==0x7fff) return (sy>=0x8000)? -pi_o_2-tiny: pi_o_2+tiny; - - /* compute y/x */ - k = sy-sx; - if(k > 70) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**70 */ - else if(sx>=0x8000&&k<-70) z=0.0; /* |y|/x < -2**70 */ - else z=__atanl(fabsl(y/x)); /* safe to do y/x */ - switch (m) { - case 0: return z ; /* atan(+,+) */ - case 1: { - u_int32_t sz; - GET_LDOUBLE_EXP(sz,z); - SET_LDOUBLE_EXP(z,sz ^ 0x8000); - } - return z ; /* atan(-,+) */ - case 2: return pi-(z-pi_lo);/* atan(+,-) */ - default: /* case 3 */ - return (z-pi_lo)-pi;/* atan(-,-) */ - } -} -strong_alias (__ieee754_atan2l, __atan2l_finite) diff --git a/sysdeps/ieee754/ldbl-96/e_hypotl.c b/sysdeps/ieee754/ldbl-96/e_hypotl.c index 7895488848..d3152f91e5 100644 --- a/sysdeps/ieee754/ldbl-96/e_hypotl.c +++ b/sysdeps/ieee754/ldbl-96/e_hypotl.c @@ -89,6 +89,17 @@ long double __ieee754_hypotl(long double x, long double y) b *= t1; a *= t1; k -= 16382; + GET_LDOUBLE_EXP (ea, a); + GET_LDOUBLE_EXP (eb, b); + if (eb > ea) + { + t1 = a; + a = b; + b = t1; + j = ea; + ea = eb; + eb = j; + } } else { /* scale a and b by 2^9600 */ ea += 0x2580; /* a *= 2^9600 */ eb += 0x2580; /* b *= 2^9600 */ diff --git a/sysdeps/ieee754/ldbl-96/e_ilogbl.c b/sysdeps/ieee754/ldbl-96/e_ilogbl.c deleted file mode 100644 index 0c7d9d5440..0000000000 --- a/sysdeps/ieee754/ldbl-96/e_ilogbl.c +++ /dev/null @@ -1,59 +0,0 @@ -/* s_ilogbl.c -- long double version of s_ilogb.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: $"; -#endif - -/* ilogbl(long double x) - * return the binary exponent of non-zero x - * ilogbl(0) = FP_ILOGB0 - * ilogbl(NaN) = FP_ILOGBNAN (no signal is raised) - * ilogbl(+-Inf) = INT_MAX (no signal is raised) - */ - -#include <limits.h> -#include <math.h> -#include <math_private.h> - -int __ieee754_ilogbl (long double x) -{ - int32_t es,hx,lx,ix; - - GET_LDOUBLE_EXP(es,x); - es &= 0x7fff; - if(es==0) { - GET_LDOUBLE_WORDS(es,hx,lx,x); - if((hx|lx)==0) - return FP_ILOGB0; /* ilogbl(0) = FP_ILOGB0 */ - else /* subnormal x */ - if(hx==0) { - for (ix = -16415; lx>0; lx<<=1) ix -=1; - } else { - for (ix = -16383; hx>0; hx<<=1) ix -=1; - } - return ix; - } - else if (es<0x7fff) return es-0x3fff; - else if (FP_ILOGBNAN != INT_MAX) - { - GET_LDOUBLE_WORDS(es,hx,lx,x); - if (((hx & 0x7fffffff)|lx) == 0) - /* ISO C99 requires ilogbl(+-Inf) == INT_MAX. */ - return INT_MAX; - } - return FP_ILOGBNAN; -} diff --git a/sysdeps/ieee754/ldbl-96/e_jnl.c b/sysdeps/ieee754/ldbl-96/e_jnl.c index 58a9107f7d..fa8e27efec 100644 --- a/sysdeps/ieee754/ldbl-96/e_jnl.c +++ b/sysdeps/ieee754/ldbl-96/e_jnl.c @@ -302,7 +302,8 @@ __ieee754_ynl (int n, long double x) if (__builtin_expect ((ix == 0x7fff) && ((i0 & 0x7fffffff) != 0), 0)) return x + x; if (__builtin_expect ((ix | i0 | i1) == 0, 0)) - return -HUGE_VALL + x; /* -inf and overflow exception. */ + /* -inf or inf and divide-by-zero exception. */ + return ((n < 0 && (n & 1) != 0) ? 1.0L : -1.0L) / 0.0L; if (__builtin_expect (se & 0x8000, 0)) return zero / (zero * x); sign = 1; diff --git a/sysdeps/ieee754/ldbl-96/e_remainderl.c b/sysdeps/ieee754/ldbl-96/e_remainderl.c deleted file mode 100644 index 290e483ae5..0000000000 --- a/sysdeps/ieee754/ldbl-96/e_remainderl.c +++ /dev/null @@ -1,72 +0,0 @@ -/* e_remainderl.c -- long double version of e_remainder.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -/* __ieee754_remainderl(x,p) - * Return : - * returns x REM p = x - [x/p]*p as if in infinite - * precise arithmetic, where [x/p] is the (infinite bit) - * integer nearest x/p (in half way case choose the even one). - * Method : - * Based on fmod() return x-[x/p]chopped*p exactlp. - */ - -#include <math.h> -#include <math_private.h> - -static const long double zero = 0.0; - - -long double -__ieee754_remainderl(long double x, long double p) -{ - u_int32_t sx,sex,sep,x0,x1,p0,p1; - long double p_half; - - GET_LDOUBLE_WORDS(sex,x0,x1,x); - GET_LDOUBLE_WORDS(sep,p0,p1,p); - sx = sex&0x8000; - sep &= 0x7fff; - sex &= 0x7fff; - - /* purge off exception values */ - if((sep|p0|p1)==0) return (x*p)/(x*p); /* p = 0 */ - if((sex==0x7fff)|| /* x not finite */ - ((sep==0x7fff)&& /* p is NaN */ - ((p0|p1)!=0))) - return (x*p)/(x*p); - - - if (sep<0x7ffe) x = __ieee754_fmodl(x,p+p); /* now x < 2p */ - if (((sex-sep)|(x0-p0)|(x1-p1))==0) return zero*x; - x = fabsl(x); - p = fabsl(p); - if (sep<0x0002) { - if(x+x>p) { - x-=p; - if(x+x>=p) x -= p; - } - } else { - p_half = 0.5*p; - if(x>p_half) { - x-=p; - if(x>=p_half) x -= p; - } - } - GET_LDOUBLE_EXP(sex,x); - SET_LDOUBLE_EXP(x,sex^sx); - return x; -} -strong_alias (__ieee754_remainderl, __remainderl_finite) diff --git a/sysdeps/ieee754/ldbl-96/printf_fphex.c b/sysdeps/ieee754/ldbl-96/printf_fphex.c index f356a4843e..715c93b500 100644 --- a/sysdeps/ieee754/ldbl-96/printf_fphex.c +++ b/sysdeps/ieee754/ldbl-96/printf_fphex.c @@ -25,11 +25,13 @@ do { \ /* The "strange" 80 bit format on ix86 and m68k has an explicit \ leading digit in the 64 bit mantissa. */ \ unsigned long long int num; \ + union ieee854_long_double u; \ + u.d = fpnum.ldbl; \ \ assert (sizeof (long double) == 12); \ \ - num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \ - | fpnum.ldbl.ieee.mantissa1); \ + num = (((unsigned long long int) u.ieee.mantissa0) << 32 \ + | u.ieee.mantissa1); \ \ zero_mantissa = num == 0; \ \ @@ -62,7 +64,7 @@ do { \ \ /* We have 3 bits from the mantissa in the leading nibble. \ Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'. */ \ - exponent = fpnum.ldbl.ieee.exponent; \ + exponent = u.ieee.exponent; \ \ if (exponent == 0) \ { \ diff --git a/sysdeps/ieee754/ldbl-96/s_ceill.c b/sysdeps/ieee754/ldbl-96/s_ceill.c deleted file mode 100644 index aef8a32f63..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_ceill.c +++ /dev/null @@ -1,85 +0,0 @@ -/* s_ceill.c -- long double version of s_ceil.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: $"; -#endif - -/* - * ceill(x) - * Return x rounded toward -inf to integral value - * Method: - * Bit twiddling. - * Exception: - * Inexact flag raised if x not equal to ceil(x). - */ - -#include <math.h> -#include <math_private.h> - -static const long double huge = 1.0e4930; - -long double __ceill(long double x) -{ - int32_t i1,j0; - u_int32_t i,j,se,i0,sx; - GET_LDOUBLE_WORDS(se,i0,i1,x); - sx = (se>>15)&1; - j0 = (se&0x7fff)-0x3fff; - if(j0<31) { - if(j0<0) { /* raise inexact if x != 0 */ - if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ - if(sx) {se=0x8000;i0=0;i1=0;} - else if((i0|i1)!=0) { se=0x3fff;i0=0;i1=0;} - } - } else { - i = (0x7fffffff)>>j0; - if(((i0&i)|i1)==0) return x; /* x is integral */ - if(huge+x>0.0) { /* raise inexact flag */ - if(sx==0) { - if (j0>0 && (i0+(0x80000000>>j0))>i0) - i0+=0x80000000>>j0; - else - { - i = 0x7fffffff; - ++se; - } - } - i0 &= (~i); i1=0; - } - } - } else if (j0>62) { - if(j0==0x4000) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } else { - i = ((u_int32_t)(0xffffffff))>>(j0-31); - if((i1&i)==0) return x; /* x is integral */ - if(huge+x>0.0) { /* raise inexact flag */ - if(sx==0) { - if(j0==31) i0+=1; - else { - j = i1 + (1<<(63-j0)); - if(j<i1) i0+=1; /* got a carry */ - i1 = j; - } - } - i1 &= (~i); - } - } - SET_LDOUBLE_WORDS(x,se,i0,i1); - return x; -} -weak_alias (__ceill, ceill) diff --git a/sysdeps/ieee754/ldbl-96/s_erfl.c b/sysdeps/ieee754/ldbl-96/s_erfl.c index 17d2278524..47e4b9e909 100644 --- a/sysdeps/ieee754/ldbl-96/s_erfl.c +++ b/sysdeps/ieee754/ldbl-96/s_erfl.c @@ -104,6 +104,7 @@ */ +#include <errno.h> #include <math.h> #include <math_private.h> @@ -422,14 +423,22 @@ __erfcl (long double x) r = __ieee754_expl (-z * z - 0.5625) * __ieee754_expl ((z - x) * (z + x) + R / S); if ((se & 0x8000) == 0) - return r / x; + { + long double ret = r / x; + if (ret == 0) + __set_errno (ERANGE); + return ret; + } else return two - r / x; } else { if ((se & 0x8000) == 0) - return tiny * tiny; + { + __set_errno (ERANGE); + return tiny * tiny; + } else return two - tiny; } diff --git a/sysdeps/ieee754/ldbl-96/s_fabsl.c b/sysdeps/ieee754/ldbl-96/s_fabsl.c deleted file mode 100644 index fdc70e0dcd..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_fabsl.c +++ /dev/null @@ -1,35 +0,0 @@ -/* s_fabsl.c -- long double version of s_fabs.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: $"; -#endif - -/* - * fabsl(x) returns the absolute value of x. - */ - -#include <math.h> -#include <math_private.h> - -long double __fabsl(long double x) -{ - u_int32_t exp; - GET_LDOUBLE_EXP(exp,x); - SET_LDOUBLE_EXP(x,exp&0x7fff); - return x; -} -weak_alias (__fabsl, fabsl) diff --git a/sysdeps/ieee754/ldbl-96/s_finitel.c b/sysdeps/ieee754/ldbl-96/s_finitel.c deleted file mode 100644 index fbf4cc691c..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_finitel.c +++ /dev/null @@ -1,36 +0,0 @@ -/* s_finitel.c -- long double version of s_finite.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: $"; -#endif - -/* - * finitel(x) returns 1 is x is finite, else 0; - * no branching! - */ - -#include <math.h> -#include <math_private.h> - -int __finitel(long double x) -{ - int32_t exp; - GET_LDOUBLE_EXP(exp,x); - return (int)((u_int32_t)((exp&0x7fff)-0x7fff)>>31); -} -hidden_def (__finitel) -weak_alias (__finitel, finitel) diff --git a/sysdeps/ieee754/ldbl-96/s_floorl.c b/sysdeps/ieee754/ldbl-96/s_floorl.c deleted file mode 100644 index cad7935b33..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_floorl.c +++ /dev/null @@ -1,86 +0,0 @@ -/* s_floorl.c -- long double version of s_floor.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: $"; -#endif - -/* - * floorl(x) - * Return x rounded toward -inf to integral value - * Method: - * Bit twiddling. - * Exception: - * Inexact flag raised if x not equal to floor(x). - */ - -#include <math.h> -#include <math_private.h> - -static const long double huge = 1.0e4930; - -long double __floorl(long double x) -{ - int32_t i1,j0; - u_int32_t i,j,se,i0,sx; - GET_LDOUBLE_WORDS(se,i0,i1,x); - sx = (se>>15)&1; - j0 = (se&0x7fff)-0x3fff; - if(j0<31) { - if(j0<0) { /* raise inexact if x != 0 */ - if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ - if(sx==0) {se=0;i0=i1=0;} - else if(((se&0x7fff)|i0|i1)!=0) - { se=0xbfff;i0=i1=0;} - } - } else { - i = (0x7fffffff)>>j0; - if(((i0&i)|i1)==0) return x; /* x is integral */ - if(huge+x>0.0) { /* raise inexact flag */ - if(sx) { - if (j0>0 && (i0+(0x80000000>>j0))>i0) - i0 += (0x80000000)>>j0; - else - { - i = 0x7fffffff; - ++se; - } - } - i0 &= (~i); i1=0; - } - } - } else if (j0>62) { - if(j0==0x4000) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } else { - i = ((u_int32_t)(0xffffffff))>>(j0-31); - if((i1&i)==0) return x; /* x is integral */ - if(huge+x>0.0) { /* raise inexact flag */ - if(sx) { - if(j0==31) i0+=1; - else { - j = i1+(1<<(63-j0)); - if(j<i1) i0 +=1 ; /* got a carry */ - i1=j; - } - } - i1 &= (~i); - } - } - SET_LDOUBLE_WORDS(x,se,i0,i1); - return x; -} -weak_alias (__floorl, floorl) diff --git a/sysdeps/ieee754/ldbl-96/s_fpclassifyl.c b/sysdeps/ieee754/ldbl-96/s_fpclassifyl.c deleted file mode 100644 index d164f86334..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_fpclassifyl.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Return classification value corresponding to argument. - Copyright (C) 1997-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. - Fixed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <math.h> - -#include <math_private.h> - - -int -__fpclassifyl (long double x) -{ - u_int32_t ex, hx, lx, m; - int retval = FP_NORMAL; - - GET_LDOUBLE_WORDS (ex, hx, lx, x); - m = (hx & 0x7fffffff) | lx; - ex &= 0x7fff; - if ((ex | m) == 0) - retval = FP_ZERO; - else if (ex == 0 && (hx & 0x80000000) == 0) - retval = FP_SUBNORMAL; - else if (ex == 0x7fff) - retval = m != 0 ? FP_NAN : FP_INFINITE; - - return retval; -} -libm_hidden_def (__fpclassifyl) diff --git a/sysdeps/ieee754/ldbl-96/s_isinfl.c b/sysdeps/ieee754/ldbl-96/s_isinfl.c deleted file mode 100644 index 94639f00f8..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_isinfl.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Written by J.T. Conklin <jtc@netbsd.org>. - * Change for long double by Ulrich Drepper <drepper@cygnus.com>. - * Public domain. - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: $"; -#endif - -/* - * isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0; - * no branching! - */ - -#include <math.h> -#include <math_private.h> - -int -__isinfl (long double x) -{ - int32_t se,hx,lx; - GET_LDOUBLE_WORDS(se,hx,lx,x); - lx |= (hx & 0x7fffffff) | ((se & 0x7fff) ^ 0x7fff); - lx |= -lx; - se &= 0x8000; - return ~(lx >> 31) & (1 - (se >> 14)); -} -hidden_def (__isinfl) -weak_alias (__isinfl, isinfl) diff --git a/sysdeps/ieee754/ldbl-96/s_isnanl.c b/sysdeps/ieee754/ldbl-96/s_isnanl.c deleted file mode 100644 index fd270fd849..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_isnanl.c +++ /dev/null @@ -1,40 +0,0 @@ -/* s_isnanl.c -- long double version of s_isnan.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: $"; -#endif - -/* - * isnanl(x) returns 1 is x is nan, else 0; - * no branching! - */ - -#include <math.h> -#include <math_private.h> - -int __isnanl(long double x) -{ - int32_t se,hx,lx; - GET_LDOUBLE_WORDS(se,hx,lx,x); - se = (se & 0x7fff) << 1; - lx |= hx & 0x7fffffff; - se |= (u_int32_t)(lx|(-lx))>>31; - se = 0xfffe - se; - return (int)(((u_int32_t)(se))>>31); -} -hidden_def (__isnanl) -weak_alias (__isnanl, isnanl) diff --git a/sysdeps/ieee754/ldbl-96/s_logbl.c b/sysdeps/ieee754/ldbl-96/s_logbl.c deleted file mode 100644 index 4289be1933..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_logbl.c +++ /dev/null @@ -1,51 +0,0 @@ -/* s_logbl.c -- long double version of s_logb.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -/* - * long double logbl(x) - * IEEE 754 logb. Included to pass IEEE test suite. Not recommend. - * Use ilogb instead. - */ - -#include <math.h> -#include <math_private.h> - -long double -__logbl (long double x) -{ - int32_t es, lx, ix; - - GET_LDOUBLE_WORDS (es, ix, lx, x); - es &= 0x7fff; /* exponent */ - if ((es | ix | lx) == 0) - return -1.0 / fabs (x); - if (es == 0x7fff) - return x * x; - if (es == 0) /* IEEE 754 logb */ - { - /* POSIX specifies that denormal number is treated as - though it were normalized. */ - int ma; - if (ix == 0) - ma = __builtin_clz (lx) + 32; - else - ma = __builtin_clz (ix); - es -= ma - 1; - } - return (long double) (es - 16383); -} - -weak_alias (__logbl, logbl) diff --git a/sysdeps/ieee754/ldbl-96/s_nearbyintl.c b/sysdeps/ieee754/ldbl-96/s_nearbyintl.c deleted file mode 100644 index c1d77f0c02..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_nearbyintl.c +++ /dev/null @@ -1,88 +0,0 @@ -/* s_rintl.c -- long double version of s_rint.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ -/* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>. */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -/* - * rintl(x) - * Return x rounded to integral value according to the prevailing - * rounding mode. - * Method: - * Using floating addition. - * Exception: - * Inexact flag raised if x not equal to rintl(x). - */ - -#include <fenv.h> -#include <math.h> -#include <math_private.h> - -static const long double -TWO63[2]={ - 9.223372036854775808000000e+18, /* 0x403E, 0x00000000, 0x00000000 */ - -9.223372036854775808000000e+18 /* 0xC03E, 0x00000000, 0x00000000 */ -}; - -long double __nearbyintl(long double x) -{ - fenv_t env; - int32_t se,j0,sx; - u_int32_t i,i0,i1; - long double w,t; - GET_LDOUBLE_WORDS(se,i0,i1,x); - sx = (se>>15)&1; - j0 = (se&0x7fff)-0x3fff; - if(j0<31) { - if(j0<0) { - if(((se&0x7fff)|i0|i1)==0) return x; - i1 |= i0; - i0 &= 0xe0000000; - i0 |= (i1|-i1)&0x80000000; - SET_LDOUBLE_MSW(x,i0); - feholdexcept (&env); - w = TWO63[sx]+x; - t = w-TWO63[sx]; - math_force_eval (t); - fesetenv (&env); - GET_LDOUBLE_EXP(i0,t); - SET_LDOUBLE_EXP(t,(i0&0x7fff)|(sx<<15)); - return t; - } else { - i = (0x7fffffff)>>j0; - if(((i0&i)|i1)==0) return x; /* x is integral */ - i>>=1; - if(((i0&i)|i1)!=0) { - if (j0==30) i1 = 0x40000000; else - i0 = (i0&(~i))|((0x20000000)>>j0); - } - } - } else if (j0>62) { - if(j0==0x4000) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } else { - i = ((u_int32_t)(0xffffffff))>>(j0-31); - if((i1&i)==0) return x; /* x is integral */ - i>>=1; - if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-31)); - } - SET_LDOUBLE_WORDS(x,se,i0,i1); - feholdexcept (&env); - w = TWO63[sx]+x; - t = w-TWO63[sx]; - math_force_eval (t); - fesetenv (&env); - return t; -} -weak_alias (__nearbyintl, nearbyintl) diff --git a/sysdeps/ieee754/ldbl-96/s_nextafterl.c b/sysdeps/ieee754/ldbl-96/s_nextafterl.c deleted file mode 100644 index 6859349b7c..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_nextafterl.c +++ /dev/null @@ -1,96 +0,0 @@ -/* s_nextafterl.c -- long double version of s_nextafter.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: $"; -#endif - -/* IEEE functions - * nextafterl(x,y) - * return the next machine floating-point number of x in the - * direction toward y. - * Special cases: - */ - -#include <math.h> -#include <math_private.h> - -long double __nextafterl(long double x, long double y) -{ - int32_t hx,hy,ix,iy; - u_int32_t lx,ly,esx,esy; - - GET_LDOUBLE_WORDS(esx,hx,lx,x); - GET_LDOUBLE_WORDS(esy,hy,ly,y); - ix = esx&0x7fff; /* |x| */ - iy = esy&0x7fff; /* |y| */ - - if (((ix==0x7fff)&&((hx|lx)!=0)) || /* x is nan */ - ((iy==0x7fff)&&((hy|ly)!=0))) /* y is nan */ - return x+y; - if(x==y) return y; /* x=y, return y */ - if((ix|hx|lx)==0) { /* x == 0 */ - long double u; - SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */ - u = math_opt_barrier (x); - u = u * u; - math_force_eval (u); /* raise underflow flag */ - return x; - } - if(esx<0x8000) { /* x > 0 */ - if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) { - /* x > y, x -= ulp */ - if(lx==0) { - if (hx==0) esx -= 1; - hx -= 1; - } - lx -= 1; - } else { /* x < y, x += ulp */ - lx += 1; - if(lx==0) { - hx += 1; - if (hx==0) - esx += 1; - } - } - } else { /* x < 0 */ - if(esy>=0||(ix>iy||((ix==iy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){ - /* x < y, x -= ulp */ - if(lx==0) { - if (hx==0) esx -= 1; - hx -= 1; - } - lx -= 1; - } else { /* x > y, x += ulp */ - lx += 1; - if(lx==0) { - hx += 1; - if (hx==0) esx += 1; - } - } - } - esy = esx&0x7fff; - if(esy==0x7fff) return x+x; /* overflow */ - if(esy==0) { - long double u = x*x; /* underflow */ - math_force_eval (u); /* raise underflow flag */ - } - SET_LDOUBLE_WORDS(x,esx,hx,lx); - return x; -} -weak_alias (__nextafterl, nextafterl) -strong_alias (__nextafterl, __nexttowardl) -weak_alias (__nextafterl, nexttowardl) diff --git a/sysdeps/ieee754/ldbl-96/s_rintl.c b/sysdeps/ieee754/ldbl-96/s_rintl.c deleted file mode 100644 index b6f899d4ef..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_rintl.c +++ /dev/null @@ -1,82 +0,0 @@ -/* s_rintl.c -- long double version of s_rint.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: $"; -#endif - -/* - * rintl(x) - * Return x rounded to integral value according to the prevailing - * rounding mode. - * Method: - * Using floating addition. - * Exception: - * Inexact flag raised if x not equal to rintl(x). - */ - -#include <math.h> -#include <math_private.h> - -static const long double -TWO63[2]={ - 9.223372036854775808000000e+18, /* 0x403E, 0x00000000, 0x00000000 */ - -9.223372036854775808000000e+18 /* 0xC03E, 0x00000000, 0x00000000 */ -}; - -long double __rintl(long double x) -{ - int32_t se,j0,sx; - u_int32_t i,i0,i1; - long double w,t; - GET_LDOUBLE_WORDS(se,i0,i1,x); - sx = (se>>15)&1; - j0 = (se&0x7fff)-0x3fff; - if(j0<31) { - if(j0<0) { - if(((se&0x7fff)|i0|i1)==0) return x; - i1 |= i0; - i0 &= 0xe0000000; - i0 |= (i1|-i1)&0x80000000; - SET_LDOUBLE_MSW(x,i0); - w = TWO63[sx]+x; - t = w-TWO63[sx]; - GET_LDOUBLE_EXP(i0,t); - SET_LDOUBLE_EXP(t,(i0&0x7fff)|(sx<<15)); - return t; - } else { - i = (0x7fffffff)>>j0; - if(((i0&i)|i1)==0) return x; /* x is integral */ - i>>=1; - if(((i0&i)|i1)!=0) { - if(j0==30) i1 = 0x40000000; else - i0 = (i0&(~i))|((0x20000000)>>j0); - } - } - } else if (j0>62) { - if(j0==0x4000) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } else { - i = ((u_int32_t)(0xffffffff))>>(j0-31); - if((i1&i)==0) return x; /* x is integral */ - i>>=1; - if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-31)); - } - SET_LDOUBLE_WORDS(x,se,i0,i1); - w = TWO63[sx]+x; - return w-TWO63[sx]; -} -weak_alias (__rintl, rintl) diff --git a/sysdeps/ieee754/ldbl-96/s_scalbnl.c b/sysdeps/ieee754/ldbl-96/s_scalbnl.c deleted file mode 100644 index 266a37b9c0..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_scalbnl.c +++ /dev/null @@ -1,61 +0,0 @@ -/* s_scalbnl.c -- long double version of s_scalbn.c. - * Conversion to long double by Ulrich Drepper, - * Cygnus Support, drepper@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by 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. - * ==================================================== - */ - -/* - * scalbnl (long double x, int n) - * scalbnl(x,n) returns x* 2**n computed by exponent - * manipulation rather than by actually performing an - * exponentiation or a multiplication. - */ - -#include <math.h> -#include <math_private.h> - -static const long double -two64 = 1.8446744073709551616e19L, -twom64 = 5.421010862427522170037e-20L, -huge = 1.0e+4900L, -tiny = 1.0e-4900L; - -long double -__scalbnl (long double x, int n) -{ - int32_t k,es,hx,lx; - GET_LDOUBLE_WORDS(es,hx,lx,x); - k = es&0x7fff; /* extract exponent */ - if (__builtin_expect(k==0, 0)) { /* 0 or subnormal x */ - if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ - x *= two64; - GET_LDOUBLE_EXP(hx,x); - k = (hx&0x7fff) - 64; - } - if (__builtin_expect(k==0x7fff, 0)) return x+x; /* NaN or Inf */ - if (__builtin_expect(n< -50000, 0)) - return tiny*__copysignl(tiny,x); - if (__builtin_expect(n> 50000 || k+n > 0x7ffe, 0)) - return huge*__copysignl(huge,x); /* overflow */ - /* Now k and n are bounded we know that k = k+n does not - overflow. */ - k = k+n; - if (__builtin_expect(k > 0, 1)) /* normal result */ - {SET_LDOUBLE_EXP(x,(es&0x8000)|k); return x;} - if (k <= -64) - return tiny*__copysignl(tiny,x); /*underflow*/ - k += 64; /* subnormal result */ - SET_LDOUBLE_EXP(x,(es&0x8000)|k); - return x*twom64; -} -weak_alias (__scalbnl, scalbnl) diff --git a/sysdeps/ieee754/ldbl-96/s_truncl.c b/sysdeps/ieee754/ldbl-96/s_truncl.c deleted file mode 100644 index cc58fb0b77..0000000000 --- a/sysdeps/ieee754/ldbl-96/s_truncl.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Truncate argument to nearest integral value not larger than the argument. - Copyright (C) 1997-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <math.h> - -#include <math_private.h> - - -long double -__truncl (long double x) -{ - int32_t i0, j0; - u_int32_t se, i1; - int sx; - - GET_LDOUBLE_WORDS (se, i0, i1, x); - sx = se & 0x8000; - j0 = (se & 0x7fff) - 0x3fff; - if (j0 < 31) - { - if (j0 < 0) - /* The magnitude of the number is < 1 so the result is +-0. */ - SET_LDOUBLE_WORDS (x, sx, 0, 0); - else - SET_LDOUBLE_WORDS (x, se, i0 & ~(0x7fffffff >> j0), 0); - } - else if (j0 > 63) - { - if (j0 == 0x4000) - /* x is inf or NaN. */ - return x + x; - } - else - { - SET_LDOUBLE_WORDS (x, se, i0, i1 & ~(0xffffffffu >> (j0 - 31))); - } - - return x; -} -weak_alias (__truncl, truncl) diff --git a/sysdeps/ieee754/ldbl-opt/configure b/sysdeps/ieee754/ldbl-opt/configure index 6e69038b93..ad9d77b88c 100644 --- a/sysdeps/ieee754/ldbl-opt/configure +++ b/sysdeps/ieee754/ldbl-opt/configure @@ -1,4 +1,4 @@ -# This file is generated from configure.in by Autoconf. DO NOT EDIT! +# This file is generated from configure.ac by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/ieee754/ldbl-opt/. diff --git a/sysdeps/ieee754/ldbl-opt/configure.in b/sysdeps/ieee754/ldbl-opt/configure.ac index a77fadd1c4..a77fadd1c4 100644 --- a/sysdeps/ieee754/ldbl-opt/configure.in +++ b/sysdeps/ieee754/ldbl-opt/configure.ac diff --git a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h index b0b863cba5..af861c11ea 100644 --- a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h +++ b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h @@ -10,7 +10,7 @@ SHLIB_COMPAT(lib, introduced, LONG_DOUBLE_COMPAT_VERSION) #define long_double_symbol(lib, local, symbol) \ long_double_symbol_1 (lib, local, symbol, LONG_DOUBLE_COMPAT_VERSION) -#if defined SHARED && defined DO_VERSIONING +#ifdef SHARED # define ldbl_hidden_def(local, name) libc_hidden_ver (local, name) # define ldbl_strong_alias(name, aliasname) \ strong_alias (name, __GL_##name##_##aliasname) \ |