inline void eval_frexp(float128_backend& result, const float128_backend& arg, int* exp) { result.value() = frexpq(arg.value(), exp); }
__float128 log2q (__float128 x) { __float128 z; __float128 y; int e; int64_t hx, lx; /* Test for domain */ GET_FLT128_WORDS64 (hx, lx, x); if (((hx & 0x7fffffffffffffffLL) | lx) == 0) return (-1.0Q / fabsq (x)); /* log2l(+-0)=-inf */ if (hx < 0) return (x - x) / (x - x); if (hx >= 0x7fff000000000000LL) return (x + x); if (x == 1.0Q) return 0.0Q; /* separate mantissa from exponent */ /* Note, frexp is used so that denormal numbers * will be handled properly. */ x = frexpq (x, &e); /* logarithm using log(x) = z + z**3 P(z)/Q(z), * where z = 2(x-1)/x+1) */ if ((e > 2) || (e < -2)) { if (x < SQRTH) { /* 2( 2x-1 )/( 2x+1 ) */ e -= 1; z = x - 0.5Q; y = 0.5Q * z + 0.5Q; } else { /* 2 (x-1)/(x+1) */ z = x - 0.5Q; z -= 0.5Q; y = 0.5Q * x + 0.5Q; } x = z / y; z = x * x; y = x * (z * neval (z, R, 5) / deval (z, S, 5)); goto done; } /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ if (x < SQRTH) { e -= 1; x = 2.0 * x - 1.0Q; /* 2x - 1 */ } else { x = x - 1.0Q; } z = x * x; y = x * (z * neval (x, P, 12) / deval (x, Q, 11)); y = y - 0.5 * z; done: /* Multiply log of fraction by log2(e) * and base 2 exponent by 1 */ z = y * LOG2EA; z += x * LOG2EA; z += y; z += x; z += e; return (z); }