[pypy-commit] pypy default: Fixed nan sign on windows

andrewjlawrence pypy.commits at gmail.com
Wed Feb 6 05:02:23 EST 2019


Author: andrewjlawrence
Branch: 
Changeset: r95857:f8548d5c059a
Date: 2019-02-05 17:17 +0000
http://bitbucket.org/pypy/pypy/changeset/f8548d5c059a/

Log:	Fixed nan sign on windows

diff --git a/rpython/rtyper/lltypesystem/module/test/math_cases.py b/rpython/rtyper/lltypesystem/module/test/math_cases.py
--- a/rpython/rtyper/lltypesystem/module/test/math_cases.py
+++ b/rpython/rtyper/lltypesystem/module/test/math_cases.py
@@ -59,9 +59,6 @@
         ('copysign', (1.5, -0.0), -1.5),
         ('copysign', (1.5, INFINITY), 1.5),
         ('copysign', (1.5, -INFINITY), -1.5),
-        ]
-    if sys.platform != 'win32':    # all NaNs seem to be negative there...?
-        IRREGCASES += [
         ('copysign', (1.5, NAN), 1.5),
         ('copysign', (1.75, -NAN), -1.75),      # special case for -NAN here
         ]
diff --git a/rpython/translator/c/primitive.py b/rpython/translator/c/primitive.py
--- a/rpython/translator/c/primitive.py
+++ b/rpython/translator/c/primitive.py
@@ -123,9 +123,9 @@
             return '(-Py_HUGE_VAL)'
     elif math.isnan(value):
         if is_positive_nan(value):
-            return '(Py_HUGE_VAL/Py_HUGE_VAL)'
+            return '(_PyPy_dg_stdnan(0))'
         else:
-            return '(-(Py_HUGE_VAL/Py_HUGE_VAL))'
+            return '(_PyPy_dg_stdnan(1))'
     else:
         x = repr(value)
         assert not x.startswith('n')
@@ -142,9 +142,9 @@
     elif math.isnan(value):
         # XXX are these expressions ok?
         if is_positive_nan(value):
-            return '((float)(Py_HUGE_VAL/Py_HUGE_VAL))'
+            return '((float)(_PyPy_dg_stdnan(0)))'
         else:
-            return '(-(float)(Py_HUGE_VAL/Py_HUGE_VAL))'
+            return '((float)(_PyPy_dg_stdnan(1)))'
     else:
         return repr(value) + 'f'
 
diff --git a/rpython/translator/c/src/support.c b/rpython/translator/c/src/support.c
--- a/rpython/translator/c/src/support.c
+++ b/rpython/translator/c/src/support.c
@@ -9,6 +9,26 @@
 #include <stdlib.h>
 
 /*** misc ***/
+#define Sign_bit 0x80000000
+#define NAN_WORD0 0x7ff80000
+#define NAN_WORD1 0
+#define PY_UINT32_T unsigned int
+
+#ifndef __BIG_ENDIAN__
+#define IEEE_8087
+#endif
+
+#ifdef IEEE_8087
+#define word0(x) (x)->L[1]
+#define word1(x) (x)->L[0]
+#else
+#define word0(x) (x)->L[0]
+#define word1(x) (x)->L[1]
+#endif
+#define dval(x) (x)->d
+
+typedef PY_UINT32_T ULong;
+typedef union { double d; ULong L[2]; } U;
 
 RPY_EXTERN
 void RPyAssertFailed(const char* filename, long lineno,
@@ -25,3 +45,20 @@
   fprintf(stderr, "Invalid RPython operation (NULL ptr or bad array index)\n");
   abort();
 }
+
+/* Return a 'standard' NaN value.
+   There are exactly two quiet NaNs that don't arise by 'quieting' signaling
+   NaNs (see IEEE 754-2008, section 6.2.1).  If sign == 0, return the one whose
+   sign bit is cleared.  Otherwise, return the one whose sign bit is set.
+*/
+
+double
+_PyPy_dg_stdnan(int sign)
+{
+    U rv;
+    word0(&rv) = NAN_WORD0;
+    word1(&rv) = NAN_WORD1;
+    if (sign)
+        word0(&rv) |= Sign_bit;
+    return dval(&rv);
+}
diff --git a/rpython/translator/c/src/support.h b/rpython/translator/c/src/support.h
--- a/rpython/translator/c/src/support.h
+++ b/rpython/translator/c/src/support.h
@@ -38,6 +38,9 @@
 RPY_EXTERN
 void RPyAbort(void);
 
+RPY_EXTERN
+double _PyPy_dg_stdnan(int sign);
+
 #if defined(RPY_LL_ASSERT) || defined(RPY_SANDBOXED)
 /* obscure macros that can be used as expressions and lvalues to refer
  * to a field of a structure or an item in an array in a "safe" way --


More information about the pypy-commit mailing list