[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