math: fix pow(x,-1) to raise underflow properly

if FLT_EVAL_METHOD!=0 check if (double)(1/x) is subnormal and not a
power of 2 (if 1/x is power of 2 then either it is exact or the
long double to double rounding already raised inexact and underflow)
This commit is contained in:
Szabolcs Nagy 2013-08-15 15:13:24 +00:00
parent 411efb3bc6
commit c221af9516
1 changed files with 14 additions and 2 deletions

View File

@ -146,8 +146,20 @@ double pow(double x, double y)
else if ((ix|lx) != 0) /* (|x|<1)**+-inf = 0,inf if x!=0 */ else if ((ix|lx) != 0) /* (|x|<1)**+-inf = 0,inf if x!=0 */
return hy >= 0 ? 0.0 : -y; return hy >= 0 ? 0.0 : -y;
} }
if (iy == 0x3ff00000) /* y is +-1 */ if (iy == 0x3ff00000) { /* y is +-1 */
return hy >= 0 ? x : 1.0/x; if (hy >= 0)
return x;
y = 1/x;
#if FLT_EVAL_METHOD!=0
{
union {double f; uint64_t i;} u = {y};
uint64_t i = u.i & -1ULL/2;
if (i>>52 == 0 && (i&(i-1)))
FORCE_EVAL((float)y);
}
#endif
return y;
}
if (hy == 0x40000000) /* y is 2 */ if (hy == 0x40000000) /* y is 2 */
return x*x; return x*x;
if (hy == 0x3fe00000) { /* y is 0.5 */ if (hy == 0x3fe00000) { /* y is 0.5 */