ix -= 23 << 23;
}
}
- double_t logx = log2_inline (ix);
- double_t ylogx = (double) y * logx; /* Note: cannot overflow, y is single prec. */
+ /* y * log2(x) cannot overflow since y is single precision. */
+ double_t ylogx = (double) y * log2_inline (ix);
+
+ /* Check whether |y*log(x)| >= 126. */
if (__glibc_unlikely ((asuint64 (ylogx) >> 47 & 0xffff)
>= asuint64 (126.0 * POWF_SCALE) >> 47))
{
- /* |y*log(x)| >= 126. */
- if (ylogx > 0x1.fffffffd1d571p+6 * POWF_SCALE)
- /* |x^y| > 0x1.ffffffp127. */
- return __math_oflowf (sign_bias);
- if (WANT_ROUNDING && WANT_ERRNO
- && ylogx > 0x1.fffffffa3aae2p+6 * POWF_SCALE)
- /* |x^y| > 0x1.fffffep127, check if we round away from 0. */
- if ((!sign_bias
- && math_narrow_eval (1.0f + math_opt_barrier (0x1p-25f)) != 1.0f)
- || (sign_bias
- && math_narrow_eval (-1.0f - math_opt_barrier (0x1p-25f))
- != -1.0f))
- return __math_oflowf (sign_bias);
+
if (ylogx <= -150.0 * POWF_SCALE)
return __math_uflowf (sign_bias);
-#if WANT_ERRNO_UFLOW
- if (ylogx < -149.0 * POWF_SCALE)
+
+ if (WANT_ERRNO_UFLOW && ylogx < -149.0 * POWF_SCALE)
return __math_may_uflowf (sign_bias);
-#endif
+
+ /* |x^y| > 0x1.ffffffp127. */
+ if (!WANT_ROUNDING && ylogx > 0x1.fffffffd1d571p+6 * POWF_SCALE)
+ return __math_oflowf (sign_bias);
+
+ if (WANT_ROUNDING && ylogx > 0x1.fffffffa3aae2p+6 * POWF_SCALE)
+ {
+ if (ylogx > 0x1.fffffffd1d571p+6 * POWF_SCALE)
+ return __math_oflowf (sign_bias);
+
+ /* |x^y| > 0x1.fffffep127, check if we round away from 0. */
+ if (ylogx != 0x1.fffffffa3aae3p+6 * POWF_SCALE)
+ {
+ float x = math_opt_barrier (0x1p-25f);
+ if ((!sign_bias && math_narrow_eval (1.0f + x) != 1.0f)
+ || (sign_bias && math_narrow_eval (-1.0f - x) != -1.0f))
+ return __math_oflowf (sign_bias);
+ }
+
+ return sign_bias ? -0x1.fffffep127 : 0x1.fffffep127;
+ }
}
return (float) exp2_inline (ylogx, sign_bias);
}