From c221af951693d526d3ae946f7e708af8e7a9bf85 Mon Sep 17 00:00:00 2001
From: Szabolcs Nagy <nsz@port70.net>
Date: Thu, 15 Aug 2013 15:13:24 +0000
Subject: 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)
---
 src/math/pow.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

(limited to 'src/math')

diff --git a/src/math/pow.c b/src/math/pow.c
index ac3abc0f..82f684bd 100644
--- a/src/math/pow.c
+++ b/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 */
-- 
cgit v1.2.3-70-g09d2