diff options
author | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2013-10-18 21:33:25 +0000 |
---|---|---|
committer | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2013-10-18 21:33:25 +0000 |
commit | fe2ed5aaa408e1ab996a9fe1595a05634208a79c (patch) | |
tree | e1027fbc9d8a4a8c33f8149b2b42e8cde89c74f6 /libc/sysdeps/ieee754/dbl-64 | |
parent | 571c782b982d888565e7d06bfc2f3d47582fe829 (diff) | |
download | eglibc2-fe2ed5aaa408e1ab996a9fe1595a05634208a79c.tar.gz |
Merge changes between r23946 and r24305 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@24306 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/sysdeps/ieee754/dbl-64')
63 files changed, 3783 insertions, 3250 deletions
diff --git a/libc/sysdeps/ieee754/dbl-64/MathLib.h b/libc/sysdeps/ieee754/dbl-64/MathLib.h index 23f71980b..cf56606e3 100644 --- a/libc/sysdeps/ieee754/dbl-64/MathLib.h +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/dbl2mpn.c b/libc/sysdeps/ieee754/dbl-64/dbl2mpn.c index f2294de5a..087d64377 100644 --- a/libc/sysdeps/ieee754/dbl-64/dbl2mpn.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/dla.h b/libc/sysdeps/ieee754/dbl-64/dla.h index b09f00ec7..6666982bf 100644 --- a/libc/sysdeps/ieee754/dbl-64/dla.h +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/dosincos.c b/libc/sysdeps/ieee754/dbl-64/dosincos.c index 00726285a..e1c8836b7 100644 --- a/libc/sysdeps/ieee754/dbl-64/dosincos.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_acosh.c b/libc/sysdeps/ieee754/dbl-64/e_acosh.c index b24a6f645..c1f3590f7 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_acosh.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_atan2.c b/libc/sysdeps/ieee754/dbl-64/e_atan2.c index 4ebe9c01f..e36305cda 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_atan2.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_cosh.c b/libc/sysdeps/ieee754/dbl-64/e_cosh.c index 229d5a2fb..6caf943ed 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_cosh.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_exp.c b/libc/sysdeps/ieee754/dbl-64/e_exp.c index 07cc4a91b..df3aa5efa 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_exp.c +++ b/libc/sysdeps/ieee754/dbl-64/e_exp.c @@ -44,221 +44,299 @@ # 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 */ + 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; + 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; - goto 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; + } } - 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: +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/libc/sysdeps/ieee754/dbl-64/e_exp2.c b/libc/sysdeps/ieee754/dbl-64/e_exp2.c index 96ec735e3..e1ba940e6 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_exp2.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_fmod.c b/libc/sysdeps/ieee754/dbl-64/e_fmod.c index b8548fae4..c83c2aedb 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_fmod.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_gamma_r.c b/libc/sysdeps/ieee754/dbl-64/e_gamma_r.c index 5b17f7b5a..13e389d7c 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_gamma_r.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_hypot.c b/libc/sysdeps/ieee754/dbl-64/e_hypot.c index 2dd681cf1..9f4321efe 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_hypot.c +++ b/libc/sysdeps/ieee754/dbl-64/e_hypot.c @@ -46,76 +46,101 @@ #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 < 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; } - /* 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/libc/sysdeps/ieee754/dbl-64/e_ilogb.c b/libc/sysdeps/ieee754/dbl-64/e_ilogb.c index 0452a71fb..1e338a59c 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_ilogb.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_j0.c b/libc/sysdeps/ieee754/dbl-64/e_j0.c index d641a0914..d165e8092 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_j0.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_j1.c b/libc/sysdeps/ieee754/dbl-64/e_j1.c index cca5f20b4..ab754c6ee 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_j1.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_jn.c b/libc/sysdeps/ieee754/dbl-64/e_jn.c index 0d2a24c93..f48e43a0d 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_jn.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_log.c b/libc/sysdeps/ieee754/dbl-64/e_log.c index f9300f9ce..a7ab54435 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_log.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_log10.c b/libc/sysdeps/ieee754/dbl-64/e_log10.c index ab5069e58..c3d465a4a 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_log10.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_log2.c b/libc/sysdeps/ieee754/dbl-64/e_log2.c index 4d5cab0ed..890a4a2bd 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_log2.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_pow.c b/libc/sysdeps/ieee754/dbl-64/e_pow.c index 9a766e722..9cf230917 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_pow.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_rem_pio2.c b/libc/sysdeps/ieee754/dbl-64/e_rem_pio2.c index 4478be0b0..2f55ca294 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_rem_pio2.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_remainder.c b/libc/sysdeps/ieee754/dbl-64/e_remainder.c index 2d20bb1df..c6a1901b1 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_remainder.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_sinh.c b/libc/sysdeps/ieee754/dbl-64/e_sinh.c index b954100ba..851b510aa 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_sinh.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/e_sqrt.c b/libc/sysdeps/ieee754/dbl-64/e_sqrt.c index 54610eeea..854ae38c4 100644 --- a/libc/sysdeps/ieee754/dbl-64/e_sqrt.c +++ b/libc/sysdeps/ieee754/dbl-64/e_sqrt.c @@ -44,58 +44,67 @@ /* 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) + { + 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; + } + 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); } - 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/libc/sysdeps/ieee754/dbl-64/halfulp.c b/libc/sysdeps/ieee754/dbl-64/halfulp.c index 8c5a9312a..382ad7aad 100644 --- a/libc/sysdeps/ieee754/dbl-64/halfulp.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/k_rem_pio2.c b/libc/sysdeps/ieee754/dbl-64/k_rem_pio2.c index ec4b4cf60..047c6c288 100644 --- a/libc/sysdeps/ieee754/dbl-64/k_rem_pio2.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/mpa-arch.h b/libc/sysdeps/ieee754/dbl-64/mpa-arch.h index 7de9d51ae..779a43d9b 100644 --- a/libc/sysdeps/ieee754/dbl-64/mpa-arch.h +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/mpa.c b/libc/sysdeps/ieee754/dbl-64/mpa.c index a3feb175e..190e8a637 100644 --- a/libc/sysdeps/ieee754/dbl-64/mpa.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/mpatan.c b/libc/sysdeps/ieee754/dbl-64/mpatan.c index 807b16a9b..a6ae61195 100644 --- a/libc/sysdeps/ieee754/dbl-64/mpatan.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/mpn2dbl.c b/libc/sysdeps/ieee754/dbl-64/mpn2dbl.c index 8a2f45b9d..0fada79a0 100644 --- a/libc/sysdeps/ieee754/dbl-64/mpn2dbl.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/mptan.c b/libc/sysdeps/ieee754/dbl-64/mptan.c index 281bfca1c..a5c3fb36c 100644 --- a/libc/sysdeps/ieee754/dbl-64/mptan.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/mydefs.h b/libc/sysdeps/ieee754/dbl-64/mydefs.h index 89ca965c6..a430397c6 100644 --- a/libc/sysdeps/ieee754/dbl-64/mydefs.h +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_asinh.c b/libc/sysdeps/ieee754/dbl-64/s_asinh.c index 68e854f5f..550074684 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_asinh.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_atan.c b/libc/sysdeps/ieee754/dbl-64/s_atan.c index 7b6c83ffb..744e96146 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_atan.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_cbrt.c b/libc/sysdeps/ieee754/dbl-64/s_cbrt.c index a7120e1e1..208a369a6 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_cbrt.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_ceil.c b/libc/sysdeps/ieee754/dbl-64/s_ceil.c index e048c81c2..b2154b407 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_ceil.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_copysign.c b/libc/sysdeps/ieee754/dbl-64/s_copysign.c index a541ceb05..9caf24e8f 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_copysign.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_erf.c b/libc/sysdeps/ieee754/dbl-64/s_erf.c index e25e28d9d..aab4ed593 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_erf.c +++ b/libc/sysdeps/ieee754/dbl-64/s_erf.c @@ -116,181 +116,176 @@ static char rcsid[] = "$NetBSD: s_erf.c,v 1.8 1995/05/10 20:47:05 jtc Exp $"; #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; - } - 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 + 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; - 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 +293,115 @@ 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; -#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; + } + 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) + return r / x; + else + return two - r / x; + } + else + { + if (hx > 0) + return tiny * tiny; + else + return two - tiny; + } } weak_alias (__erfc, erfc) #ifdef NO_LONG_DOUBLE diff --git a/libc/sysdeps/ieee754/dbl-64/s_expm1.c b/libc/sysdeps/ieee754/dbl-64/s_expm1.c index 1a4bcd979..9c9bb3455 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_expm1.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_fabs.c b/libc/sysdeps/ieee754/dbl-64/s_fabs.c index 86f1d52be..c82c4210e 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_fabs.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_finite.c b/libc/sysdeps/ieee754/dbl-64/s_finite.c index 47dad5df2..5dc398efc 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_finite.c +++ b/libc/sysdeps/ieee754/dbl-64/s_finite.c @@ -23,11 +23,12 @@ 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) +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/libc/sysdeps/ieee754/dbl-64/s_floor.c b/libc/sysdeps/ieee754/dbl-64/s_floor.c index 5c7297842..bd6afa72e 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_floor.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_frexp.c b/libc/sysdeps/ieee754/dbl-64/s_frexp.c index 516f561a1..1b8d8500b 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_frexp.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_isinf.c b/libc/sysdeps/ieee754/dbl-64/s_isinf.c index 886b346f5..46a7266e7 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_isinf.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_isinf_ns.c b/libc/sysdeps/ieee754/dbl-64/s_isinf_ns.c index 0ce50352c..d8142bcf6 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_isinf_ns.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_isnan.c b/libc/sysdeps/ieee754/dbl-64/s_isnan.c index f8958dcbb..5d9f31be2 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_isnan.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_llround.c b/libc/sysdeps/ieee754/dbl-64/s_llround.c index e8c2232e9..7d50a57dd 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_llround.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_log1p.c b/libc/sysdeps/ieee754/dbl-64/s_log1p.c index e3e686096..ea1dc6ca7 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_log1p.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_logb.c b/libc/sysdeps/ieee754/dbl-64/s_logb.c index 17aa94b75..c065826dd 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_logb.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_lrint.c b/libc/sysdeps/ieee754/dbl-64/s_lrint.c index a68c97e59..1c3037364 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_lrint.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_modf.c b/libc/sysdeps/ieee754/dbl-64/s_modf.c index b9911c1af..1dce6381a 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_modf.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_nearbyint.c b/libc/sysdeps/ieee754/dbl-64/s_nearbyint.c index 5017f471d..dec0c5d6e 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_nearbyint.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_remquo.c b/libc/sysdeps/ieee754/dbl-64/s_remquo.c index 642581ede..c40615004 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_remquo.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_rint.c b/libc/sysdeps/ieee754/dbl-64/s_rint.c index 845890916..a9c0d2784 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_rint.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_scalbln.c b/libc/sysdeps/ieee754/dbl-64/s_scalbln.c index 271a24c3e..6402927d2 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_scalbln.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_scalbn.c b/libc/sysdeps/ieee754/dbl-64/s_scalbn.c index 1f302557e..6e7d5ad21 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_scalbn.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_sin.c b/libc/sysdeps/ieee754/dbl-64/s_sin.c index 5c388c8b9..53eef6002 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_sin.c +++ b/libc/sysdeps/ieee754/dbl-64/s_sin.c @@ -55,6 +55,59 @@ #include <math_private.h> #include <fenv.h> +/* Helper macros to compute sin of the input values. */ +#define POLYNOMIAL2(xx) ((((s5.x * (xx) + s4.x) * (xx) + s3.x) * (xx) + s2.x) \ + * (xx)) + +#define POLYNOMIAL(xx) (POLYNOMIAL2 (xx) + s1.x) + +/* 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_SINCOS(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.x * x1 * x1 * x1; \ + double r = (x0) + y; \ + double x2 = ((x0) - x1) + (dx); \ + double t = (((POLYNOMIAL2 (xx) + bb.x) * xx + 3.0 * aa.x * x1 * x2) \ + * (x0) + aa.x * 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 @@ -74,10 +127,8 @@ static const double 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 +144,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,21 +197,16 @@ __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) @@ -137,16 +216,16 @@ __sin (double x) 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 ----------------------*/ @@ -167,16 +246,11 @@ __sin (double x) 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 ----------------------*/ @@ -204,14 +278,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_SINCOS (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 { @@ -232,18 +302,13 @@ __sin (double x) 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; @@ -257,11 +322,7 @@ __sin (double x) u.x = big.x + a; y = a - (u.x - big.x) + 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,11 +331,8 @@ __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 --------------------*/ @@ -307,14 +365,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_SINCOS (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 { @@ -335,18 +389,13 @@ __sin (double x) 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; @@ -360,11 +409,7 @@ __sin (double x) u.x = big.x + a; y = a - (u.x - big.x) + 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 +418,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 +432,8 @@ __sin (double x) if (k == 0x7ff00000 && u.i[LOW_HALF] == 0) __set_errno (EDOM); retval = x / x; - goto ret; } -ret: return retval; } @@ -444,11 +460,9 @@ __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 */ @@ -458,16 +472,11 @@ __cos (double x) 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) @@ -478,13 +487,9 @@ __cos (double x) 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_SINCOS (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 { @@ -505,18 +510,13 @@ __cos (double x) 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) */ @@ -546,13 +546,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_SINCOS (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 { @@ -573,18 +569,13 @@ __cos (double x) 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; @@ -598,11 +589,7 @@ __cos (double x) u.x = big.x + a; y = a - (u.x - big.x) + 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,8 +598,6 @@ __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 ) */ @@ -646,13 +631,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_SINCOS (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 { @@ -673,18 +654,13 @@ __cos (double x) 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; @@ -698,11 +674,7 @@ __cos (double x) u.x = big.x + a; y = a - (u.x - big.x) + 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 +683,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 +710,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 +720,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 */ /*******************************************************************************/ @@ -802,18 +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); 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); } } @@ -846,7 +775,6 @@ 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; if (y >= 0) @@ -864,11 +792,7 @@ slow2 (double x) 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; @@ -889,7 +813,7 @@ slow2 (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); } } @@ -905,24 +829,14 @@ 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; + double y, t, res, cor, w[2], a, da, xn; union { int4 i[2]; double x; } 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; + res = TAYLOR_SLOW (x, dx, cor); cor = (cor > 0) ? 1.0005 * cor + ABS (orig) * 3.1e-30 : 1.0005 * cor - @@ -966,7 +880,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); } } } @@ -985,7 +899,6 @@ 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; @@ -994,11 +907,7 @@ sloww1 (double x, double dx, double orig) 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 +937,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); } } @@ -1046,7 +955,6 @@ 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; @@ -1055,11 +963,7 @@ sloww2 (double x, double dx, double orig, int n) 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 +994,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 +1010,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 +1026,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); } } @@ -1150,7 +1044,6 @@ 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; @@ -1159,11 +1052,7 @@ bsloww1 (double x, double dx, double orig, int n) 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 +1077,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); } } @@ -1206,7 +1095,6 @@ 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; @@ -1215,11 +1103,7 @@ bsloww2 (double x, double dx, double orig, int n) 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 +1129,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); } } @@ -1261,7 +1145,6 @@ 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; @@ -1269,11 +1152,7 @@ cslow2 (double x) 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 +1171,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,8 +1187,7 @@ 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; + double y, t, res, cor, w[2], a, da, xn; union { int4 i[2]; @@ -1317,17 +1195,8 @@ csloww (double x, double dx, double orig) } 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; @@ -1375,7 +1244,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); } } } @@ -1394,7 +1263,6 @@ 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; @@ -1403,11 +1271,7 @@ csloww1 (double x, double dx, double orig) 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 +1299,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); } } @@ -1454,7 +1318,6 @@ 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; @@ -1463,11 +1326,7 @@ csloww2 (double x, double dx, double orig, int n) 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 +1355,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/libc/sysdeps/ieee754/dbl-64/s_sincos.c b/libc/sysdeps/ieee754/dbl-64/s_sincos.c index b6d5432f4..01d1bdf97 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_sincos.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_tan.c b/libc/sysdeps/ieee754/dbl-64/s_tan.c index 54f863e54..09db096d0 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_tan.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/s_tanh.c b/libc/sysdeps/ieee754/dbl-64/s_tanh.c index ded0d6025..23cfcdead 100644 --- a/libc/sysdeps/ieee754/dbl-64/s_tanh.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/sincos32.c b/libc/sysdeps/ieee754/dbl-64/sincos32.c index 954db66d6..f253b8ce8 100644 --- a/libc/sysdeps/ieee754/dbl-64/sincos32.c +++ b/libc/sysdeps/ieee754/dbl-64/sincos32.c @@ -48,312 +48,318 @@ # 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) + return (res < res1) ? res : res1; + else + return (res > res1) ? res : res1; } -/************************************************************************/ -/*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) + return (res > res1) ? res : res1; + else + return (res < res1) ? res : res1; } -/*******************************************************************/ -/*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); - } + 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); + } + 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/libc/sysdeps/ieee754/dbl-64/slowexp.c b/libc/sysdeps/ieee754/dbl-64/slowexp.c index 8f353f634..525224f44 100644 --- a/libc/sysdeps/ieee754/dbl-64/slowexp.c +++ b/libc/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/libc/sysdeps/ieee754/dbl-64/slowpow.c b/libc/sysdeps/ieee754/dbl-64/slowpow.c index a379728b1..d200c39e5 100644 --- a/libc/sysdeps/ieee754/dbl-64/slowpow.c +++ b/libc/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; } |