- x *= two54;
- GET_HIGH_WORD(hx,x);
- }
- if (hx >= 0x7ff00000)
- return x+x;
- k += (hx>>20) - 1023;
- hx &= 0x000fffff;
- i = (hx+0x95f64)&0x100000;
- SET_HIGH_WORD(x, hx|(i^0x3ff00000)); /* normalize x or x/2 */
- k += i>>20;
+ x *= 0x1p54;
+ u.f = x;
+ hx = u.i>>32;
+ } else if (hx >= 0x7ff00000) {
+ return x;
+ } else if (hx == 0x3ff00000 && u.i<<32 == 0)
+ return 0;
+
+ /* reduce x into [sqrt(2)/2, sqrt(2)] */
+ hx += 0x3ff00000 - 0x3fe6a09e;
+ k += (int)(hx>>20) - 0x3ff;
+ hx = (hx&0x000fffff) + 0x3fe6a09e;
+ u.i = (uint64_t)hx<<32 | (u.i&0xffffffff);
+ x = u.f;
+