A few minor corrections, including some from bde:

- When y/x is huge, it's faster and more accurate to return pi/2
  instead of pi - pi/2.
- There's no need for 3 lines of bit fiddling to compute -z.
- Fix a comment.
This commit is contained in:
David Schultz 2008-08-02 19:17:00 +00:00
parent 87a8e294f5
commit 9d7d093689
3 changed files with 16 additions and 17 deletions

View File

@ -109,17 +109,15 @@ __ieee754_atan2(double y, double x)
/* compute y/x */
k = (iy-ix)>>20;
if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */
else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */
if(k > 60) { /* |y/x| > 2**60 */
z=pi_o_2+0.5*pi_lo;
m&=1;
}
else if(hx<0&&k<-60) z=0.0; /* 0 > |y|/x > -2**-60 */
else z=atan(fabs(y/x)); /* safe to do y/x */
switch (m) {
case 0: return z ; /* atan(+,+) */
case 1: {
u_int32_t zh;
GET_HIGH_WORD(zh,z);
SET_HIGH_WORD(z,zh ^ 0x80000000);
}
return z ; /* atan(-,+) */
case 1: return -z ; /* atan(-,+) */
case 2: return pi-(z-pi_lo);/* atan(+,-) */
default: /* case 3 */
return (z-pi_lo)-pi;/* atan(-,-) */

View File

@ -80,17 +80,15 @@ __ieee754_atan2f(float y, float x)
/* compute y/x */
k = (iy-ix)>>23;
if(k > 26) z=pi_o_2+(float)0.5*pi_lo; /* |y/x| > 2**26 */
else if(hx<0&&k<-26) z=0.0; /* |y|/x < -2**26 */
if(k > 26) { /* |y/x| > 2**26 */
z=pi_o_2+(float)0.5*pi_lo;
m&=1;
}
else if(hx<0&&k<-26) z=0.0; /* 0 > |y|/x > -2**-26 */
else z=atanf(fabsf(y/x)); /* safe to do y/x */
switch (m) {
case 0: return z ; /* atan(+,+) */
case 1: {
u_int32_t zh;
GET_FLOAT_WORD(zh,z);
SET_FLOAT_WORD(z,zh ^ 0x80000000);
}
return z ; /* atan(-,+) */
case 1: return -z ; /* atan(-,+) */
case 2: return pi-(z-pi_lo);/* atan(+,-) */
default: /* case 3 */
return (z-pi_lo)-pi;/* atan(-,-) */

View File

@ -104,7 +104,10 @@ atan2l(long double y, long double x)
/* compute y/x */
k = expty-exptx;
if(k > LDBL_MANT_DIG+2) z=pio2_hi+pio2_lo; /* |y/x| huge */
if(k > LDBL_MANT_DIG+2) { /* |y/x| huge */
z=pio2_hi+pio2_lo;
m&=1;
}
else if(expsignx<0&&k<-LDBL_MANT_DIG-2) z=0.0; /* |y/x| tiny, x<0 */
else z=atanl(fabsl(y/x)); /* safe to do y/x */
switch (m) {