1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
};
-static const double
-one = 1.0,
-huge = 1.0e300;
-
double atan(double x)
{
- double w,s1,s2,z;
- int32_t ix,hx,id;
+ double_t w,s1,s2,z;
+ uint32_t ix,sign;
+ int id;
- GET_HIGH_WORD(hx, x);
- ix = hx & 0x7fffffff;
+ GET_HIGH_WORD(ix, x);
+ sign = ix >> 31;
+ ix &= 0x7fffffff;
if (ix >= 0x44100000) { /* if |x| >= 2^66 */
- uint32_t low;
-
- GET_LOW_WORD(low, x);
- if (ix > 0x7ff00000 ||
- (ix == 0x7ff00000 && low != 0)) /* NaN */
- return x+x;
- if (hx > 0)
- return atanhi[3] + *(volatile double *)&atanlo[3];
- else
- return -atanhi[3] - *(volatile double *)&atanlo[3];
+ if (isnan(x))
+ return x;
+ z = atanhi[3] + 0x1p-120f;
+ return sign ? -z : z;
}
if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
if (ix < 0x3e400000) { /* |x| < 2^-27 */
- /* raise inexact */
- if (huge+x > one)
- return x;
+ /* raise inexact if x!=0 */
+ FORCE_EVAL(x + 0x1p120f);
+ return x;
}
id = -1;
} else {
if (ix < 0x3ff30000) { /* |x| < 1.1875 */
if (ix < 0x3fe60000) { /* 7/16 <= |x| < 11/16 */
id = 0;
- x = (2.0*x-one)/(2.0+x);
+ x = (2.0*x-1.0)/(2.0+x);
} else { /* 11/16 <= |x| < 19/16 */
id = 1;
- x = (x-one)/(x+one);
+ x = (x-1.0)/(x+1.0);
}
} else {
if (ix < 0x40038000) { /* |x| < 2.4375 */
id = 2;
- x = (x-1.5)/(one+1.5*x);
+ x = (x-1.5)/(1.0+1.5*x);
} else { /* 2.4375 <= |x| < 2^66 */
id = 3;
x = -1.0/x;
if (id < 0)
return x - x*(s1+s2);
z = atanhi[id] - (x*(s1+s2) - atanlo[id] - x);
- return hx < 0 ? -z : z;
+ return sign ? -z : z;
}