فهرست منبع

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)
Szabolcs Nagy 11 سال پیش
والد
کامیت
c221af9516
1فایلهای تغییر یافته به همراه14 افزوده شده و 2 حذف شده
  1. 14 2
      src/math/pow.c

+ 14 - 2
src/math/pow.c

@@ -146,8 +146,20 @@ double pow(double x, double y)
 			else if ((ix|lx) != 0)     /* (|x|<1)**+-inf = 0,inf if x!=0 */
 				return hy >= 0 ? 0.0 : -y;
 		}
-		if (iy == 0x3ff00000)    /* y is +-1 */
-			return hy >= 0 ? x : 1.0/x;
+		if (iy == 0x3ff00000) {    /* y is +-1 */
+			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 */
 			return x*x;
 		if (hy == 0x3fe00000) {  /* y is 0.5 */