long double __fabsl(long double x) { uint64_t hx, lx; double xhi, xlo; ldbl_unpack (x, &xhi, &xlo); EXTRACT_WORDS64 (hx, xhi); EXTRACT_WORDS64 (lx, xlo); lx = lx ^ ( hx & 0x8000000000000000LL ); hx = hx & 0x7fffffffffffffffLL; INSERT_WORDS64 (xhi, hx); INSERT_WORDS64 (xlo, lx); x = ldbl_pack (xhi, xlo); return x; }
double __ieee754_log10 (double x) { double y, z; int64_t i, hx; int32_t k; EXTRACT_WORDS64 (hx, x); k = 0; if (hx < INT64_C(0x0010000000000000)) { /* x < 2**-1022 */ if (__builtin_expect ((hx & UINT64_C(0x7fffffffffffffff)) == 0, 0)) return -two54 / (x - x); /* log(+-0)=-inf */ if (__builtin_expect (hx < 0, 0)) return (x - x) / (x - x); /* log(-#) = NaN */ k -= 54; x *= two54; /* subnormal number, scale up x */ EXTRACT_WORDS64 (hx, x); } /* scale up resulted in a NaN number */ if (__builtin_expect (hx >= UINT64_C(0x7ff0000000000000), 0)) return x + x; k += (hx >> 52) - 1023; i = ((uint64_t) k & UINT64_C(0x8000000000000000)) >> 63; hx = (hx & UINT64_C(0x000fffffffffffff)) | ((0x3ff - i) << 52); y = (double) (k + i); INSERT_WORDS64 (x, hx); z = y * log10_2lo + ivln10 * __ieee754_log (x); return z + y * log10_2hi; }
double __roundeven (double x) { uint64_t ix, ux; EXTRACT_WORDS64 (ix, x); ux = ix & 0x7fffffffffffffffULL; int exponent = ux >> (MANT_DIG - 1); if (exponent >= BIAS + MANT_DIG - 1) { /* Integer, infinity or NaN. */ if (exponent == MAX_EXP) /* Infinity or NaN; quiet signaling NaNs. */ return x + x; else return x; } else if (exponent >= BIAS) { /* At least 1; not necessarily an integer. Locate the bits with exponents 0 and -1 (when the unbiased exponent is 0, the bit with exponent 0 is implicit, but as the bias is odd it is OK to take it from the low bit of the exponent). */ int int_pos = (BIAS + MANT_DIG - 1) - exponent; int half_pos = int_pos - 1; uint64_t half_bit = 1ULL << half_pos; uint64_t int_bit = 1ULL << int_pos; if ((ix & (int_bit | (half_bit - 1))) != 0) /* Carry into the exponent works correctly. No need to test whether HALF_BIT is set. */ ix += half_bit; ix &= ~(int_bit - 1); } else if (exponent == BIAS - 1 && ux > 0x3fe0000000000000ULL) /* Interval (0.5, 1). */ ix = (ix & 0x8000000000000000ULL) | 0x3ff0000000000000ULL; else /* Rounds to 0. */ ix &= 0x8000000000000000ULL; INSERT_WORDS64 (x, ix); return x; }
double __remquo (double x, double y, int *quo) { int64_t hx, hy; uint64_t sx, qs; int cquo; EXTRACT_WORDS64 (hx, x); EXTRACT_WORDS64 (hy, y); sx = hx & UINT64_C(0x8000000000000000); qs = sx ^ (hy & UINT64_C(0x8000000000000000)); hy &= UINT64_C(0x7fffffffffffffff); hx &= UINT64_C(0x7fffffffffffffff); /* Purge off exception values. */ if (__glibc_unlikely (hy == 0)) return (x * y) / (x * y); /* y = 0 */ if (__builtin_expect (hx >= UINT64_C(0x7ff0000000000000) /* x not finite */ || hy > UINT64_C(0x7ff0000000000000), 0))/* y is NaN */ return (x * y) / (x * y); if (hy <= UINT64_C(0x7fbfffffffffffff)) x = __ieee754_fmod (x, 8 * y); /* now x < 8y */ if (__glibc_unlikely (hx == hy)) { *quo = qs ? -1 : 1; return zero * x; } x = fabs (x); INSERT_WORDS64 (y, hy); cquo = 0; if (hy <= UINT64_C(0x7fcfffffffffffff) && x >= 4 * y) { x -= 4 * y; cquo += 4; } if (hy <= UINT64_C(0x7fdfffffffffffff) && x >= 2 * y) { x -= 2 * y; cquo += 2; } if (hy < UINT64_C(0x0020000000000000)) { if (x + x > y) { x -= y; ++cquo; if (x + x >= y) { x -= y; ++cquo; } } } else { double y_half = 0.5 * y; if (x > y_half) { x -= y; ++cquo; if (x >= y_half) { x -= y; ++cquo; } } } *quo = qs ? -cquo : cquo; /* Ensure correct sign of zero result in round-downward mode. */ if (x == 0.0) x = 0.0; if (sx) x = -x; return x; }