#include #include /* dekker exact mult u*u == hi + lo */ static void sq(long double *hi, long double *lo, long double u) { static const long double c = 1.0 + 0x1p33; long double cu, u1, u2; cu = c*u; u1 = (u - cu) + cu; u2 = u - u1; *hi = u*u; *lo = (u1*u1 - *hi) + u1*u2*2.0 + u2*u2; } /* correctly rounded double sqrt using long double arithmetics for x87 */ double x_sqrt(double x) { union { long double x; struct{ uint64_t m; uint16_t es; uint16_t pad; } bits; } u; long double r, hi, lo; u.x = sqrtl(x); if ((u.bits.m&0x7ff) == 0x400) { if ((u.bits.es&0x7fff) == 0x7fff) return u.x; sq(&hi, &lo, u.x); r = x - hi - lo; if (r > 0) u.bits.m++; else u.bits.m--; return u.x; } return u.x; }