long double __truncl (long double x) { double xh, xl, hi, lo; ldbl_unpack (x, &xh, &xl); /* Return Inf, Nan, +/-0 unchanged. */ if (__builtin_expect (xh != 0.0 && __builtin_isless (__builtin_fabs (xh), __builtin_inf ()), 1)) { hi = __trunc (xh); if (hi != xh) { /* The high part is not an integer; the low part does not affect the result. */ xh = hi; xl = 0; } else { /* The high part is a nonzero integer. */ lo = xh > 0 ? __floor (xl) : __ceil (xl); xh = hi; xl = lo; ldbl_canonicalize_int (&xh, &xl); } } return ldbl_pack (xh, xl); }
long double __roundl (long double x) { double xh, xl, hi, lo; ldbl_unpack (x, &xh, &xl); /* Return Inf, Nan, +/-0 unchanged. */ if (__builtin_expect (xh != 0.0 && __builtin_isless (__builtin_fabs (xh), __builtin_inf ()), 1)) { hi = __round (xh); if (hi != xh) { /* The high part is not an integer; the low part only affects the result if the high part is exactly half way between two integers and the low part is nonzero with the opposite sign. */ if (fabs (hi - xh) == 0.5) { if (xh > 0 && xl < 0) xh = hi - 1; else if (xh < 0 && xl > 0) xh = hi + 1; else xh = hi; } else xh = hi; xl = 0; } else { /* The high part is a nonzero integer. */ lo = __round (xl); if (fabs (lo - xl) == 0.5) { if (xh > 0 && xl < 0) xl = lo + 1; else if (xh < 0 && lo > 0) xl = lo - 1; else xl = lo; } else xl = lo; xh = hi; ldbl_canonicalize_int (&xh, &xl); } } else /* Quiet signaling NaN arguments. */ xh += xh; return ldbl_pack (xh, xl); }
long double __roundevenl (long double x) { double xh, xl, hi; ldbl_unpack (x, &xh, &xl); if (xh != 0 && isfinite (xh)) { hi = __roundeven (xh); if (hi != xh) { /* The high part is not an integer; the low part only affects the result if the high part is exactly half way between two integers and the low part is nonzero in the opposite direction to the rounding of the high part. */ double diff = hi - xh; if (fabs (diff) == 0.5) { if (xl < 0 && diff > 0) xh = hi - 1; else if (xl > 0 && diff < 0) xh = hi + 1; else xh = hi; } else xh = hi; xl = 0; } else { /* The high part is a nonzero integer. Rounding the low part to nearest, ties round to even, is always correct, as a high part that is an odd integer together with a low part with magnitude 0.5 is not a valid long double. */ xl = __roundeven (xl); xh = hi; ldbl_canonicalize_int (&xh, &xl); } } else /* Quiet signaling NaN arguments. */ xh += xh; return ldbl_pack (xh, xl); }