[PATCH 3/3] newlib/libm/math: Make pow/powf return qnan for snan arg

Keith Packard via Newlib <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
The IEEE spec for pow only has special case for x**0 and 1**y when x/y
are quiet NaN. For signaling NaN, the general case applies and these functions
should signal the invalid exception and return a quiet NaN.

Signed-off-by: Keith Packard <[email protected]>
---
 newlib/libm/math/e_pow.c  | 13 +++++++++----
 newlib/libm/math/ef_pow.c | 10 +++++++---
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/newlib/libm/math/e_pow.c b/newlib/libm/math/e_pow.c
index 5fd28e65f..4c450ec05 100644
--- a/newlib/libm/math/e_pow.c
+++ b/newlib/libm/math/e_pow.c
@@ -58,6 +58,8 @@
  */
 
 #include "fdlibm.h"
+#include "math_config.h"
+
 #if __OBSOLETE_MATH
 
 #ifndef _DOUBLE_IS_32BITS
@@ -116,14 +118,17 @@ ivln2_l  =  1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
 	EXTRACT_WORDS(hy,ly,y);
 	ix = hx&0x7fffffff;  iy = hy&0x7fffffff;
 
-    /* y==zero: x**0 = 1 */
-	if((iy|ly)==0) return one; 	
+    /* y==zero: x**0 = 1 unless x is snan */
+	if((iy|ly)==0) {
+	    if (issignaling_inline(x)) return x + y;
+	    return one;
+	}
 
     /* x|y==NaN return NaN unless x==1 then return 1 */
 	if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
 	   iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) {
-	    if(((hx-0x3ff00000)|lx)==0) return one;
-	    else return nan("");	
+	    if(((hx-0x3ff00000)|lx)==0 && !issignaling_inline(y)) return one;
+	    else return x + y;
 	}
 
     /* determine if y is an odd int when x < 0
diff --git a/newlib/libm/math/ef_pow.c b/newlib/libm/math/ef_pow.c
index d9e85a95e..d4ea4c5e8 100644
--- a/newlib/libm/math/ef_pow.c
+++ b/newlib/libm/math/ef_pow.c
@@ -14,6 +14,7 @@
  */
 
 #include "fdlibm.h"
+#include "math_config.h"
 
 #if __OBSOLETE_MATH
 #ifdef __v810__
@@ -74,13 +75,16 @@ ivln2_l  =  7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
 	ix = hx&0x7fffffff;  iy = hy&0x7fffffff;
 
     /* y==zero: x**0 = 1 */
-	if(FLT_UWORD_IS_ZERO(iy)) return one; 	
+	if(FLT_UWORD_IS_ZERO(iy)) {
+	    if (issignalingf_inline(x)) return x + y;
+	    return one;
+	}
 
     /* x|y==NaN return NaN unless x==1 then return 1 */
 	if(FLT_UWORD_IS_NAN(ix) ||
 	   FLT_UWORD_IS_NAN(iy)) {
-	    if(hx==0x3f800000) return one;
-	    else return nanf("");
+	    if(hx==0x3f800000 && !issignalingf_inline(y)) return one;
+	    else return x + y;
 	}
 
     /* determine if y is an odd int when x < 0
-- 
2.25.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.