diff options
Diffstat (limited to 'sysdeps/ieee754/dbl-64/e_hypot.c')
-rw-r--r-- | sysdeps/ieee754/dbl-64/e_hypot.c | 157 |
1 files changed, 91 insertions, 66 deletions
diff --git a/sysdeps/ieee754/dbl-64/e_hypot.c b/sysdeps/ieee754/dbl-64/e_hypot.c index 2dd681cf1a..9f4321efe1 100644 --- a/sysdeps/ieee754/dbl-64/e_hypot.c +++ b/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) |