mirror of
https://github.com/fluencelabs/musl
synced 2025-05-29 23:51:34 +00:00
Merge remote-tracking branch 'nsz/review'
This commit is contained in:
commit
83af1dd65a
@ -12,7 +12,7 @@
|
|||||||
* kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
|
* kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
|
||||||
* Input x is assumed to be bounded by ~pi/4 in magnitude.
|
* Input x is assumed to be bounded by ~pi/4 in magnitude.
|
||||||
* Input y is the tail of x.
|
* Input y is the tail of x.
|
||||||
* Input k indicates whether tan (if k = 1) or -1/tan (if k = -1) is returned.
|
* Input odd indicates whether tan (if odd = 0) or -1/tan (if odd = 1) is returned.
|
||||||
*
|
*
|
||||||
* Algorithm
|
* Algorithm
|
||||||
* 1. Since tan(-x) = -tan(x), we need only to consider positive x.
|
* 1. Since tan(-x) = -tan(x), we need only to consider positive x.
|
||||||
@ -63,21 +63,22 @@ static const double T[] = {
|
|||||||
pio4 = 7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */
|
pio4 = 7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */
|
||||||
pio4lo = 3.06161699786838301793e-17; /* 3C81A626, 33145C07 */
|
pio4lo = 3.06161699786838301793e-17; /* 3C81A626, 33145C07 */
|
||||||
|
|
||||||
double __tan(double x, double y, int iy)
|
double __tan(double x, double y, int odd)
|
||||||
{
|
{
|
||||||
double_t z, r, v, w, s, sign;
|
double_t z, r, v, w, s, a;
|
||||||
int32_t ix, hx;
|
double w0, a0;
|
||||||
|
uint32_t hx;
|
||||||
|
int big, sign;
|
||||||
|
|
||||||
GET_HIGH_WORD(hx,x);
|
GET_HIGH_WORD(hx,x);
|
||||||
ix = hx & 0x7fffffff; /* high word of |x| */
|
big = (hx&0x7fffffff) >= 0x3FE59428; /* |x| >= 0.6744 */
|
||||||
if (ix >= 0x3FE59428) { /* |x| >= 0.6744 */
|
if (big) {
|
||||||
if (hx < 0) {
|
sign = hx>>31;
|
||||||
|
if (sign) {
|
||||||
x = -x;
|
x = -x;
|
||||||
y = -y;
|
y = -y;
|
||||||
}
|
}
|
||||||
z = pio4 - x;
|
x = (pio4 - x) + (pio4lo - y);
|
||||||
w = pio4lo - y;
|
|
||||||
x = z + w;
|
|
||||||
y = 0.0;
|
y = 0.0;
|
||||||
}
|
}
|
||||||
z = x * x;
|
z = x * x;
|
||||||
@ -90,30 +91,20 @@ double __tan(double x, double y, int iy)
|
|||||||
r = T[1] + w*(T[3] + w*(T[5] + w*(T[7] + w*(T[9] + w*T[11]))));
|
r = T[1] + w*(T[3] + w*(T[5] + w*(T[7] + w*(T[9] + w*T[11]))));
|
||||||
v = z*(T[2] + w*(T[4] + w*(T[6] + w*(T[8] + w*(T[10] + w*T[12])))));
|
v = z*(T[2] + w*(T[4] + w*(T[6] + w*(T[8] + w*(T[10] + w*T[12])))));
|
||||||
s = z * x;
|
s = z * x;
|
||||||
r = y + z * (s * (r + v) + y);
|
r = y + z*(s*(r + v) + y) + s*T[0];
|
||||||
r += T[0] * s;
|
|
||||||
w = x + r;
|
w = x + r;
|
||||||
if (ix >= 0x3FE59428) {
|
if (big) {
|
||||||
v = iy;
|
s = 1 - 2*odd;
|
||||||
sign = 1 - ((hx >> 30) & 2);
|
v = s - 2.0 * (x + (r - w*w/(w + s)));
|
||||||
return sign * (v - 2.0 * (x - (w * w / (w + v) - r)));
|
return sign ? -v : v;
|
||||||
}
|
}
|
||||||
if (iy == 1)
|
if (!odd)
|
||||||
return w;
|
return w;
|
||||||
else {
|
/* -1.0/(x+r) has up to 2ulp error, so compute it accurately */
|
||||||
/*
|
w0 = w;
|
||||||
* if allow error up to 2 ulp, simply return
|
SET_LOW_WORD(w0, 0);
|
||||||
* -1.0 / (x+r) here
|
v = r - (w0 - x); /* w0+v = r+x */
|
||||||
*/
|
a0 = a = -1.0 / w;
|
||||||
/* compute -1.0 / (x+r) accurately */
|
SET_LOW_WORD(a0, 0);
|
||||||
double_t a;
|
return a0 + a*(1.0 + a0*w0 + a0*v);
|
||||||
double z, t;
|
|
||||||
z = w;
|
|
||||||
SET_LOW_WORD(z,0);
|
|
||||||
v = r - (z - x); /* z+v = r+x */
|
|
||||||
t = a = -1.0 / w; /* a = -1.0/w */
|
|
||||||
SET_LOW_WORD(t,0);
|
|
||||||
s = 1.0 + t * z;
|
|
||||||
return t + a * (s + t * v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ static const double T[] = {
|
|||||||
0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */
|
0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */
|
||||||
};
|
};
|
||||||
|
|
||||||
float __tandf(double x, int iy)
|
float __tandf(double x, int odd)
|
||||||
{
|
{
|
||||||
double_t z,r,w,s,t,u;
|
double_t z,r,w,s,t,u;
|
||||||
|
|
||||||
@ -50,6 +50,5 @@ float __tandf(double x, int iy)
|
|||||||
s = z*x;
|
s = z*x;
|
||||||
u = T[0] + z*T[1];
|
u = T[0] + z*T[1];
|
||||||
r = (x + s*u) + (s*w)*(t + w*r);
|
r = (x + s*u) + (s*w)*(t + w*r);
|
||||||
if(iy==1) return r;
|
return odd ? -1.0/r : r;
|
||||||
else return -1.0/r;
|
|
||||||
}
|
}
|
||||||
|
@ -45,25 +45,21 @@ T29 = 0.0000078293456938132840, /* 0x106b59141a6cb3.0p-69 */
|
|||||||
T31 = -0.0000032609076735050182, /* -0x1b5abef3ba4b59.0p-71 */
|
T31 = -0.0000032609076735050182, /* -0x1b5abef3ba4b59.0p-71 */
|
||||||
T33 = 0.0000023261313142559411; /* 0x13835436c0c87f.0p-71 */
|
T33 = 0.0000023261313142559411; /* 0x13835436c0c87f.0p-71 */
|
||||||
|
|
||||||
long double __tanl(long double x, long double y, int iy) {
|
long double __tanl(long double x, long double y, int odd) {
|
||||||
long double z, r, v, w, s, a, t;
|
long double z, r, v, w, s, a, t;
|
||||||
long double osign;
|
int big, sign;
|
||||||
int i;
|
|
||||||
|
|
||||||
iy = iy == 1 ? -1 : 1; /* XXX recover original interface */
|
big = fabsl(x) >= 0.67434;
|
||||||
osign = copysignl(1.0, x);
|
if (big) {
|
||||||
if (fabsl(x) >= 0.67434) {
|
sign = 0;
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
|
sign = 1;
|
||||||
x = -x;
|
x = -x;
|
||||||
y = -y;
|
y = -y;
|
||||||
}
|
}
|
||||||
z = pio4 - x;
|
x = (pio4 - x) + (pio4lo - y);
|
||||||
w = pio4lo - y;
|
|
||||||
x = z + w;
|
|
||||||
y = 0.0;
|
y = 0.0;
|
||||||
i = 1;
|
}
|
||||||
} else
|
|
||||||
i = 0;
|
|
||||||
z = x * x;
|
z = x * x;
|
||||||
w = z * z;
|
w = z * z;
|
||||||
r = T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 +
|
r = T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 +
|
||||||
@ -71,14 +67,14 @@ long double __tanl(long double x, long double y, int iy) {
|
|||||||
v = z * (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 +
|
v = z * (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 +
|
||||||
w * (T27 + w * T31))))));
|
w * (T27 + w * T31))))));
|
||||||
s = z * x;
|
s = z * x;
|
||||||
r = y + z * (s * (r + v) + y);
|
r = y + z * (s * (r + v) + y) + T3 * s;
|
||||||
r += T3 * s;
|
|
||||||
w = x + r;
|
w = x + r;
|
||||||
if (i == 1) {
|
if (big) {
|
||||||
v = (long double)iy;
|
s = 1 - 2*odd;
|
||||||
return osign * (v - 2.0 * (x - (w * w / (w + v) - r)));
|
v = s - 2.0 * (x + (r - w * w / (w + s)));
|
||||||
|
return sign ? -v : v;
|
||||||
}
|
}
|
||||||
if (iy == 1)
|
if (!odd)
|
||||||
return w;
|
return w;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -44,26 +44,28 @@
|
|||||||
|
|
||||||
double cos(double x)
|
double cos(double x)
|
||||||
{
|
{
|
||||||
double y[2],z=0.0;
|
double y[2];
|
||||||
int32_t n, ix;
|
uint32_t ix;
|
||||||
|
unsigned n;
|
||||||
|
|
||||||
GET_HIGH_WORD(ix, x);
|
GET_HIGH_WORD(ix, x);
|
||||||
|
ix &= 0x7fffffff;
|
||||||
|
|
||||||
/* |x| ~< pi/4 */
|
/* |x| ~< pi/4 */
|
||||||
ix &= 0x7fffffff;
|
|
||||||
if (ix <= 0x3fe921fb) {
|
if (ix <= 0x3fe921fb) {
|
||||||
if (ix < 0x3e46a09e) /* if x < 2**-27 * sqrt(2) */
|
if (ix < 0x3e46a09e) { /* |x| < 2**-27 * sqrt(2) */
|
||||||
/* raise inexact if x != 0 */
|
/* raise inexact if x!=0 */
|
||||||
if ((int)x == 0)
|
FORCE_EVAL(x + 0x1p120f);
|
||||||
return 1.0;
|
return 1.0;
|
||||||
return __cos(x, z);
|
}
|
||||||
|
return __cos(x, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cos(Inf or NaN) is NaN */
|
/* cos(Inf or NaN) is NaN */
|
||||||
if (ix >= 0x7ff00000)
|
if (ix >= 0x7ff00000)
|
||||||
return x-x;
|
return x-x;
|
||||||
|
|
||||||
/* argument reduction needed */
|
/* argument reduction */
|
||||||
n = __rem_pio2(x, y);
|
n = __rem_pio2(x, y);
|
||||||
switch (n&3) {
|
switch (n&3) {
|
||||||
case 0: return __cos(y[0], y[1]);
|
case 0: return __cos(y[0], y[1]);
|
||||||
|
@ -26,34 +26,39 @@ c4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
|
|||||||
float cosf(float x)
|
float cosf(float x)
|
||||||
{
|
{
|
||||||
double y;
|
double y;
|
||||||
int32_t n, hx, ix;
|
uint32_t ix;
|
||||||
|
unsigned n, sign;
|
||||||
|
|
||||||
|
GET_FLOAT_WORD(ix, x);
|
||||||
|
sign = ix >> 31;
|
||||||
|
ix &= 0x7fffffff;
|
||||||
|
|
||||||
GET_FLOAT_WORD(hx, x);
|
|
||||||
ix = hx & 0x7fffffff;
|
|
||||||
if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
|
if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
|
||||||
if (ix < 0x39800000) /* |x| < 2**-12 */
|
if (ix < 0x39800000) { /* |x| < 2**-12 */
|
||||||
if ((int)x == 0) /* raise inexact if x != 0 */
|
/* raise inexact if x != 0 */
|
||||||
return 1.0;
|
FORCE_EVAL(x + 0x1p120f);
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
return __cosdf(x);
|
return __cosdf(x);
|
||||||
}
|
}
|
||||||
if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
|
if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
|
||||||
if (ix > 0x4016cbe3) /* |x| ~> 3*pi/4 */
|
if (ix > 0x4016cbe3) /* |x| ~> 3*pi/4 */
|
||||||
return -__cosdf(hx > 0 ? x-c2pio2 : x+c2pio2);
|
return -__cosdf(sign ? x+c2pio2 : x-c2pio2);
|
||||||
else {
|
else {
|
||||||
if (hx > 0)
|
if (sign)
|
||||||
return __sindf(c1pio2 - x);
|
|
||||||
else
|
|
||||||
return __sindf(x + c1pio2);
|
return __sindf(x + c1pio2);
|
||||||
|
else
|
||||||
|
return __sindf(c1pio2 - x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
|
if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
|
||||||
if (ix > 0x40afeddf) /* |x| ~> 7*pi/4 */
|
if (ix > 0x40afeddf) /* |x| ~> 7*pi/4 */
|
||||||
return __cosdf(hx > 0 ? x-c4pio2 : x+c4pio2);
|
return __cosdf(sign ? x+c4pio2 : x-c4pio2);
|
||||||
else {
|
else {
|
||||||
if (hx > 0)
|
if (sign)
|
||||||
return __sindf(x - c3pio2);
|
return __sindf(-x - c3pio2);
|
||||||
else
|
else
|
||||||
return __sindf(-c3pio2 - x);
|
return __sindf(x - c3pio2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,30 +39,30 @@ long double cosl(long double x) {
|
|||||||
long double cosl(long double x)
|
long double cosl(long double x)
|
||||||
{
|
{
|
||||||
union IEEEl2bits z;
|
union IEEEl2bits z;
|
||||||
int e0;
|
unsigned n;
|
||||||
long double y[2];
|
long double y[2];
|
||||||
long double hi, lo;
|
long double hi, lo;
|
||||||
|
|
||||||
z.e = x;
|
z.e = x;
|
||||||
z.bits.sign = 0;
|
z.bits.sign = 0;
|
||||||
|
|
||||||
/* If x = +-0 or x is a subnormal number, then cos(x) = 1 */
|
|
||||||
if (z.bits.exp == 0)
|
|
||||||
return 1.0;
|
|
||||||
|
|
||||||
/* If x = NaN or Inf, then cos(x) = NaN. */
|
/* If x = NaN or Inf, then cos(x) = NaN. */
|
||||||
if (z.bits.exp == 32767)
|
if (z.bits.exp == 0x7fff)
|
||||||
return (x - x) / (x - x);
|
return (x - x) / (x - x);
|
||||||
|
|
||||||
/* Optimize the case where x is already within range. */
|
/* |x| < (double)pi/4 */
|
||||||
if (z.e < M_PI_4)
|
if (z.e < M_PI_4) {
|
||||||
|
/* |x| < 0x1p-64 */
|
||||||
|
if (z.bits.exp < 0x3fff - 64)
|
||||||
|
/* raise inexact if x!=0 */
|
||||||
|
return 1.0 + x;
|
||||||
return __cosl(z.e, 0);
|
return __cosl(z.e, 0);
|
||||||
|
}
|
||||||
|
|
||||||
e0 = __rem_pio2l(x, y);
|
n = __rem_pio2l(x, y);
|
||||||
hi = y[0];
|
hi = y[0];
|
||||||
lo = y[1];
|
lo = y[1];
|
||||||
|
switch (n & 3) {
|
||||||
switch (e0 & 3) {
|
|
||||||
case 0:
|
case 0:
|
||||||
hi = __cosl(hi, lo);
|
hi = __cosl(hi, lo);
|
||||||
break;
|
break;
|
||||||
|
@ -44,21 +44,22 @@
|
|||||||
|
|
||||||
double sin(double x)
|
double sin(double x)
|
||||||
{
|
{
|
||||||
double y[2], z=0.0;
|
double y[2];
|
||||||
int32_t n, ix;
|
uint32_t ix;
|
||||||
|
unsigned n;
|
||||||
|
|
||||||
/* High word of x. */
|
/* High word of x. */
|
||||||
GET_HIGH_WORD(ix, x);
|
GET_HIGH_WORD(ix, x);
|
||||||
|
ix &= 0x7fffffff;
|
||||||
|
|
||||||
/* |x| ~< pi/4 */
|
/* |x| ~< pi/4 */
|
||||||
ix &= 0x7fffffff;
|
|
||||||
if (ix <= 0x3fe921fb) {
|
if (ix <= 0x3fe921fb) {
|
||||||
if (ix < 0x3e500000) { /* |x| < 2**-26 */
|
if (ix < 0x3e500000) { /* |x| < 2**-26 */
|
||||||
/* raise inexact if x != 0 */
|
/* raise inexact if x != 0 and underflow if subnormal*/
|
||||||
if ((int)x == 0)
|
FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
return __sin(x, z, 0);
|
return __sin(x, 0.0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sin(Inf or NaN) is NaN */
|
/* sin(Inf or NaN) is NaN */
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
void sincos(double x, double *sin, double *cos)
|
void sincos(double x, double *sin, double *cos)
|
||||||
{
|
{
|
||||||
double y[2], s, c;
|
double y[2], s, c;
|
||||||
uint32_t n, ix;
|
uint32_t ix;
|
||||||
|
unsigned n;
|
||||||
|
|
||||||
GET_HIGH_WORD(ix, x);
|
GET_HIGH_WORD(ix, x);
|
||||||
ix &= 0x7fffffff;
|
ix &= 0x7fffffff;
|
||||||
@ -24,11 +25,10 @@ void sincos(double x, double *sin, double *cos)
|
|||||||
if (ix <= 0x3fe921fb) {
|
if (ix <= 0x3fe921fb) {
|
||||||
/* if |x| < 2**-27 * sqrt(2) */
|
/* if |x| < 2**-27 * sqrt(2) */
|
||||||
if (ix < 0x3e46a09e) {
|
if (ix < 0x3e46a09e) {
|
||||||
/* raise inexact if x != 0 */
|
/* raise inexact if x!=0 and underflow if subnormal */
|
||||||
if ((int)x == 0) {
|
FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
|
||||||
*sin = x;
|
*sin = x;
|
||||||
*cos = 1.0;
|
*cos = 1.0;
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*sin = __sin(x, 0.0, 0);
|
*sin = __sin(x, 0.0, 0);
|
||||||
|
@ -25,21 +25,23 @@ s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
|
|||||||
|
|
||||||
void sincosf(float x, float *sin, float *cos)
|
void sincosf(float x, float *sin, float *cos)
|
||||||
{
|
{
|
||||||
double y, s, c;
|
double y;
|
||||||
uint32_t n, hx, ix;
|
float_t s, c;
|
||||||
|
uint32_t ix;
|
||||||
|
unsigned n, sign;
|
||||||
|
|
||||||
GET_FLOAT_WORD(hx, x);
|
GET_FLOAT_WORD(ix, x);
|
||||||
ix = hx & 0x7fffffff;
|
sign = ix >> 31;
|
||||||
|
ix &= 0x7fffffff;
|
||||||
|
|
||||||
/* |x| ~<= pi/4 */
|
/* |x| ~<= pi/4 */
|
||||||
if (ix <= 0x3f490fda) {
|
if (ix <= 0x3f490fda) {
|
||||||
/* |x| < 2**-12 */
|
/* |x| < 2**-12 */
|
||||||
if (ix < 0x39800000) {
|
if (ix < 0x39800000) {
|
||||||
/* raise inexact if x != 0 */
|
/* raise inexact if x!=0 and underflow if subnormal */
|
||||||
if((int)x == 0) {
|
FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
|
||||||
*sin = x;
|
*sin = x;
|
||||||
*cos = 1.0f;
|
*cos = 1.0f;
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*sin = __sindf(x);
|
*sin = __sindf(x);
|
||||||
@ -50,34 +52,35 @@ void sincosf(float x, float *sin, float *cos)
|
|||||||
/* |x| ~<= 5*pi/4 */
|
/* |x| ~<= 5*pi/4 */
|
||||||
if (ix <= 0x407b53d1) {
|
if (ix <= 0x407b53d1) {
|
||||||
if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */
|
if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */
|
||||||
if (hx < 0x80000000) {
|
if (sign) {
|
||||||
*sin = __cosdf(x - s1pio2);
|
|
||||||
*cos = __sindf(s1pio2 - x);
|
|
||||||
} else {
|
|
||||||
*sin = -__cosdf(x + s1pio2);
|
*sin = -__cosdf(x + s1pio2);
|
||||||
*cos = __sindf(x + s1pio2);
|
*cos = __sindf(x + s1pio2);
|
||||||
|
} else {
|
||||||
|
*sin = __cosdf(s1pio2 - x);
|
||||||
|
*cos = __sindf(s1pio2 - x);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*sin = __sindf(hx < 0x80000000 ? s2pio2 - x : -s2pio2 - x);
|
/* -sin(x+c) is not correct if x+c could be 0: -0 vs +0 */
|
||||||
*cos = -__cosdf(hx < 0x80000000 ? x - s2pio2 : x + s2pio2);
|
*sin = -__sindf(sign ? x + s2pio2 : x - s2pio2);
|
||||||
|
*cos = -__cosdf(sign ? x + s2pio2 : x - s2pio2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* |x| ~<= 9*pi/4 */
|
/* |x| ~<= 9*pi/4 */
|
||||||
if (ix <= 0x40e231d5) {
|
if (ix <= 0x40e231d5) {
|
||||||
if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */
|
if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */
|
||||||
if (hx < 0x80000000) {
|
if (sign) {
|
||||||
|
*sin = __cosdf(x + s3pio2);
|
||||||
|
*cos = -__sindf(x + s3pio2);
|
||||||
|
} else {
|
||||||
*sin = -__cosdf(x - s3pio2);
|
*sin = -__cosdf(x - s3pio2);
|
||||||
*cos = __sindf(x - s3pio2);
|
*cos = __sindf(x - s3pio2);
|
||||||
} else {
|
|
||||||
*sin = __cosdf(x + s3pio2);
|
|
||||||
*cos = __sindf(-s3pio2 - x);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*sin = __sindf(hx < 0x80000000 ? x - s4pio2 : x + s4pio2);
|
*sin = __sindf(sign ? x + s4pio2 : x - s4pio2);
|
||||||
*cos = __cosdf(hx < 0x80000000 ? x - s4pio2 : x + s4pio2);
|
*cos = __cosdf(sign ? x + s4pio2 : x - s4pio2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,27 +10,29 @@ void sincosl(long double x, long double *sin, long double *cos)
|
|||||||
void sincosl(long double x, long double *sin, long double *cos)
|
void sincosl(long double x, long double *sin, long double *cos)
|
||||||
{
|
{
|
||||||
union IEEEl2bits u;
|
union IEEEl2bits u;
|
||||||
int n;
|
unsigned n;
|
||||||
long double y[2], s, c;
|
long double y[2], s, c;
|
||||||
|
|
||||||
u.e = x;
|
u.e = x;
|
||||||
u.bits.sign = 0;
|
u.bits.sign = 0;
|
||||||
|
|
||||||
/* x = +-0 or subnormal */
|
|
||||||
if (!u.bits.exp) {
|
|
||||||
*sin = x;
|
|
||||||
*cos = 1.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* x = nan or inf */
|
/* x = nan or inf */
|
||||||
if (u.bits.exp == 0x7fff) {
|
if (u.bits.exp == 0x7fff) {
|
||||||
*sin = *cos = x - x;
|
*sin = *cos = x - x;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* |x| < pi/4 */
|
/* |x| < (double)pi/4 */
|
||||||
if (u.e < M_PI_4) {
|
if (u.e < M_PI_4) {
|
||||||
|
/* |x| < 0x1p-64 */
|
||||||
|
if (u.bits.exp < 0x3fff - 64) {
|
||||||
|
/* raise underflow if subnormal */
|
||||||
|
if (u.bits.exp == 0) FORCE_EVAL(x*0x1p-120f);
|
||||||
|
*sin = x;
|
||||||
|
/* raise inexact if x!=0 */
|
||||||
|
*cos = 1.0 + x;
|
||||||
|
return;
|
||||||
|
}
|
||||||
*sin = __sinl(x, 0, 0);
|
*sin = __sinl(x, 0, 0);
|
||||||
*cos = __cosl(x, 0);
|
*cos = __cosl(x, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -26,35 +26,38 @@ s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
|
|||||||
float sinf(float x)
|
float sinf(float x)
|
||||||
{
|
{
|
||||||
double y;
|
double y;
|
||||||
int32_t n, hx, ix;
|
uint32_t ix;
|
||||||
|
int n, sign;
|
||||||
|
|
||||||
GET_FLOAT_WORD(hx, x);
|
GET_FLOAT_WORD(ix, x);
|
||||||
ix = hx & 0x7fffffff;
|
sign = ix >> 31;
|
||||||
|
ix &= 0x7fffffff;
|
||||||
|
|
||||||
if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
|
if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
|
||||||
if (ix < 0x39800000) /* |x| < 2**-12 */
|
if (ix < 0x39800000) { /* |x| < 2**-12 */
|
||||||
/* raise inexact if x != 0 */
|
/* raise inexact if x!=0 and underflow if subnormal */
|
||||||
if((int)x == 0)
|
FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f);
|
||||||
return x;
|
return x;
|
||||||
|
}
|
||||||
return __sindf(x);
|
return __sindf(x);
|
||||||
}
|
}
|
||||||
if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
|
if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
|
||||||
if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */
|
if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */
|
||||||
if (hx > 0)
|
if (sign)
|
||||||
return __cosdf(x - s1pio2);
|
|
||||||
else
|
|
||||||
return -__cosdf(x + s1pio2);
|
return -__cosdf(x + s1pio2);
|
||||||
|
else
|
||||||
|
return __cosdf(x - s1pio2);
|
||||||
}
|
}
|
||||||
return __sindf(hx > 0 ? s2pio2 - x : -s2pio2 - x);
|
return __sindf(sign ? -(x + s2pio2) : -(x - s2pio2));
|
||||||
}
|
}
|
||||||
if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
|
if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
|
||||||
if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */
|
if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */
|
||||||
if (hx > 0)
|
if (sign)
|
||||||
return -__cosdf(x - s3pio2);
|
|
||||||
else
|
|
||||||
return __cosdf(x + s3pio2);
|
return __cosdf(x + s3pio2);
|
||||||
|
else
|
||||||
|
return -__cosdf(x - s3pio2);
|
||||||
}
|
}
|
||||||
return __sindf(hx > 0 ? x - s4pio2 : x + s4pio2);
|
return __sindf(sign ? x + s4pio2 : x - s4pio2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sin(Inf or NaN) is NaN */
|
/* sin(Inf or NaN) is NaN */
|
||||||
|
@ -37,33 +37,32 @@ long double sinl(long double x)
|
|||||||
long double sinl(long double x)
|
long double sinl(long double x)
|
||||||
{
|
{
|
||||||
union IEEEl2bits z;
|
union IEEEl2bits z;
|
||||||
int e0, s;
|
unsigned n;
|
||||||
long double y[2];
|
long double y[2];
|
||||||
long double hi, lo;
|
long double hi, lo;
|
||||||
|
|
||||||
z.e = x;
|
z.e = x;
|
||||||
s = z.bits.sign;
|
|
||||||
z.bits.sign = 0;
|
z.bits.sign = 0;
|
||||||
|
|
||||||
/* If x = +-0 or x is a subnormal number, then sin(x) = x */
|
|
||||||
if (z.bits.exp == 0)
|
|
||||||
return x;
|
|
||||||
|
|
||||||
/* If x = NaN or Inf, then sin(x) = NaN. */
|
/* If x = NaN or Inf, then sin(x) = NaN. */
|
||||||
if (z.bits.exp == 32767)
|
if (z.bits.exp == 0x7fff)
|
||||||
return (x - x) / (x - x);
|
return (x - x) / (x - x);
|
||||||
|
|
||||||
/* Optimize the case where x is already within range. */
|
/* |x| < (double)pi/4 */
|
||||||
if (z.e < M_PI_4) {
|
if (z.e < M_PI_4) {
|
||||||
hi = __sinl(z.e, 0, 0);
|
/* |x| < 0x1p-64 */
|
||||||
return s ? -hi : hi;
|
if (z.bits.exp < 0x3fff - 64) {
|
||||||
|
/* raise inexact if x!=0 and underflow if subnormal */
|
||||||
|
FORCE_EVAL(z.bits.exp == 0 ? x/0x1p120f : x+0x1p120f);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
return __sinl(x, 0.0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
e0 = __rem_pio2l(x, y);
|
n = __rem_pio2l(x, y);
|
||||||
hi = y[0];
|
hi = y[0];
|
||||||
lo = y[1];
|
lo = y[1];
|
||||||
|
switch (n & 3) {
|
||||||
switch (e0 & 3) {
|
|
||||||
case 0:
|
case 0:
|
||||||
hi = __sinl(hi, lo, 1);
|
hi = __sinl(hi, lo, 1);
|
||||||
break;
|
break;
|
||||||
@ -71,10 +70,10 @@ long double sinl(long double x)
|
|||||||
hi = __cosl(hi, lo);
|
hi = __cosl(hi, lo);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
hi = - __sinl(hi, lo, 1);
|
hi = -__sinl(hi, lo, 1);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
hi = - __cosl(hi, lo);
|
hi = -__cosl(hi, lo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return hi;
|
return hi;
|
||||||
|
@ -43,27 +43,28 @@
|
|||||||
|
|
||||||
double tan(double x)
|
double tan(double x)
|
||||||
{
|
{
|
||||||
double y[2], z = 0.0;
|
double y[2];
|
||||||
int32_t n, ix;
|
uint32_t ix;
|
||||||
|
unsigned n;
|
||||||
|
|
||||||
/* High word of x. */
|
|
||||||
GET_HIGH_WORD(ix, x);
|
GET_HIGH_WORD(ix, x);
|
||||||
|
ix &= 0x7fffffff;
|
||||||
|
|
||||||
/* |x| ~< pi/4 */
|
/* |x| ~< pi/4 */
|
||||||
ix &= 0x7fffffff;
|
|
||||||
if (ix <= 0x3fe921fb) {
|
if (ix <= 0x3fe921fb) {
|
||||||
if (ix < 0x3e400000) /* x < 2**-27 */
|
if (ix < 0x3e400000) { /* |x| < 2**-27 */
|
||||||
/* raise inexact if x != 0 */
|
/* raise inexact if x!=0 and underflow if subnormal */
|
||||||
if ((int)x == 0)
|
FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
|
||||||
return x;
|
return x;
|
||||||
return __tan(x, z, 1);
|
}
|
||||||
|
return __tan(x, 0.0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tan(Inf or NaN) is NaN */
|
/* tan(Inf or NaN) is NaN */
|
||||||
if (ix >= 0x7ff00000)
|
if (ix >= 0x7ff00000)
|
||||||
return x - x;
|
return x - x;
|
||||||
|
|
||||||
/* argument reduction needed */
|
/* argument reduction */
|
||||||
n = __rem_pio2(x, y);
|
n = __rem_pio2(x, y);
|
||||||
return __tan(y[0], y[1], 1 - ((n&1)<<1)); /* n even: 1, n odd: -1 */
|
return __tan(y[0], y[1], n&1);
|
||||||
}
|
}
|
||||||
|
@ -26,37 +26,39 @@ t4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
|
|||||||
float tanf(float x)
|
float tanf(float x)
|
||||||
{
|
{
|
||||||
double y;
|
double y;
|
||||||
int32_t n, hx, ix;
|
uint32_t ix;
|
||||||
|
unsigned n, sign;
|
||||||
|
|
||||||
GET_FLOAT_WORD(hx, x);
|
GET_FLOAT_WORD(ix, x);
|
||||||
ix = hx & 0x7fffffff;
|
sign = ix >> 31;
|
||||||
|
ix &= 0x7fffffff;
|
||||||
|
|
||||||
if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
|
if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
|
||||||
if (ix < 0x39800000) /* |x| < 2**-12 */
|
if (ix < 0x39800000) { /* |x| < 2**-12 */
|
||||||
/* return x and raise inexact if x != 0 */
|
/* raise inexact if x!=0 and underflow if subnormal */
|
||||||
if ((int)x == 0)
|
FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f);
|
||||||
return x;
|
return x;
|
||||||
return __tandf(x, 1);
|
}
|
||||||
|
return __tandf(x, 0);
|
||||||
}
|
}
|
||||||
if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
|
if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
|
||||||
if (ix <= 0x4016cbe3) /* |x| ~<= 3pi/4 */
|
if (ix <= 0x4016cbe3) /* |x| ~<= 3pi/4 */
|
||||||
return __tandf((hx > 0 ? x-t1pio2 : x+t1pio2), -1);
|
return __tandf((sign ? x+t1pio2 : x-t1pio2), 1);
|
||||||
else
|
else
|
||||||
return __tandf((hx > 0 ? x-t2pio2 : x+t2pio2), 1);
|
return __tandf((sign ? x+t2pio2 : x-t2pio2), 0);
|
||||||
}
|
}
|
||||||
if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
|
if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
|
||||||
if (ix <= 0x40afeddf) /* |x| ~<= 7*pi/4 */
|
if (ix <= 0x40afeddf) /* |x| ~<= 7*pi/4 */
|
||||||
return __tandf((hx > 0 ? x-t3pio2 : x+t3pio2), -1);
|
return __tandf((sign ? x+t3pio2 : x-t3pio2), 1);
|
||||||
else
|
else
|
||||||
return __tandf((hx > 0 ? x-t4pio2 : x+t4pio2), 1);
|
return __tandf((sign ? x+t4pio2 : x-t4pio2), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tan(Inf or NaN) is NaN */
|
/* tan(Inf or NaN) is NaN */
|
||||||
if (ix >= 0x7f800000)
|
if (ix >= 0x7f800000)
|
||||||
return x - x;
|
return x - x;
|
||||||
|
|
||||||
/* general argument reduction needed */
|
/* argument reduction */
|
||||||
n = __rem_pio2f(x, &y);
|
n = __rem_pio2f(x, &y);
|
||||||
/* integer parameter: n even: 1; n odd: -1 */
|
return __tandf(y, n&1);
|
||||||
return __tandf(y, 1-((n&1)<<1));
|
|
||||||
}
|
}
|
||||||
|
@ -41,42 +41,28 @@ long double tanl(long double x)
|
|||||||
long double tanl(long double x)
|
long double tanl(long double x)
|
||||||
{
|
{
|
||||||
union IEEEl2bits z;
|
union IEEEl2bits z;
|
||||||
int e0, s;
|
|
||||||
long double y[2];
|
long double y[2];
|
||||||
long double hi, lo;
|
unsigned n;
|
||||||
|
|
||||||
z.e = x;
|
z.e = x;
|
||||||
s = z.bits.sign;
|
|
||||||
z.bits.sign = 0;
|
z.bits.sign = 0;
|
||||||
|
|
||||||
/* If x = +-0 or x is subnormal, then tan(x) = x. */
|
|
||||||
if (z.bits.exp == 0)
|
|
||||||
return x;
|
|
||||||
|
|
||||||
/* If x = NaN or Inf, then tan(x) = NaN. */
|
/* If x = NaN or Inf, then tan(x) = NaN. */
|
||||||
if (z.bits.exp == 32767)
|
if (z.bits.exp == 0x7fff)
|
||||||
return (x - x) / (x - x);
|
return (x - x) / (x - x);
|
||||||
|
|
||||||
/* Optimize the case where x is already within range. */
|
/* |x| < (double)pi/4 */
|
||||||
if (z.e < M_PI_4) {
|
if (z.e < M_PI_4) {
|
||||||
hi = __tanl(z.e, 0, 0);
|
/* |x| < 0x1p-64 */
|
||||||
return s ? -hi : hi;
|
if (z.bits.exp < 0x3fff - 64) {
|
||||||
|
/* raise inexact if x!=0 and underflow if subnormal */
|
||||||
|
FORCE_EVAL(z.bits.exp == 0 ? x/0x1p120f : x+0x1p120f);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
return __tanl(x, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
e0 = __rem_pio2l(x, y);
|
n = __rem_pio2l(x, y);
|
||||||
hi = y[0];
|
return __tanl(y[0], y[1], n&1);
|
||||||
lo = y[1];
|
|
||||||
|
|
||||||
switch (e0 & 3) {
|
|
||||||
case 0:
|
|
||||||
case 2:
|
|
||||||
hi = __tanl(hi, lo, 0);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
case 3:
|
|
||||||
hi = __tanl(hi, lo, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return hi;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user