[Python-checkins] r57284 - in python/trunk: Lib/test/test_float.py Python/compile.c
alex.martelli
python-checkins at python.org
Wed Aug 22 23:14:18 CEST 2007
Author: alex.martelli
Date: Wed Aug 22 23:14:17 2007
New Revision: 57284
Modified:
python/trunk/Lib/test/test_float.py
python/trunk/Python/compile.c
Log:
Fix compile.c so that it records 0.0 and -0.0 as separate constants in a code
object's co_consts tuple; add a test to show that the previous behavior (where
these two constants were "collapsed" into one) causes serious malfunctioning.
Modified: python/trunk/Lib/test/test_float.py
==============================================================================
--- python/trunk/Lib/test/test_float.py (original)
+++ python/trunk/Lib/test/test_float.py Wed Aug 22 23:14:17 2007
@@ -81,6 +81,7 @@
# on an IEEE platform, all we guarantee is that bit patterns
# representing infinities or NaNs do not raise an exception; all else
# is accident (today).
+# let's also try to guarantee that -0.0 and 0.0 don't get confused.
class IEEEFormatTestCase(unittest.TestCase):
if float.__getformat__("double").startswith("IEEE"):
@@ -99,6 +100,20 @@
('<f', LE_FLOAT_NAN)]:
struct.unpack(fmt, data)
+ if float.__getformat__("double").startswith("IEEE"):
+ def test_negative_zero(self):
+ import math
+ def pos_pos():
+ return 0.0, math.atan2(0.0, -1)
+ def pos_neg():
+ return 0.0, math.atan2(-0.0, -1)
+ def neg_pos():
+ return -0.0, math.atan2(0.0, -1)
+ def neg_neg():
+ return -0.0, math.atan2(-0.0, -1)
+ self.assertEquals(pos_pos(), neg_pos())
+ self.assertEquals(pos_neg(), neg_neg())
+
def test_main():
test_support.run_unittest(
Modified: python/trunk/Python/compile.c
==============================================================================
--- python/trunk/Python/compile.c (original)
+++ python/trunk/Python/compile.c Wed Aug 22 23:14:17 2007
@@ -907,7 +907,20 @@
Py_ssize_t arg;
/* necessary to make sure types aren't coerced (e.g., int and long) */
- t = PyTuple_Pack(2, o, o->ob_type);
+ /* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */
+ if (PyFloat_Check(o)) {
+ double d = PyFloat_AS_DOUBLE(o);
+ unsigned char* p = (unsigned char*) &d;
+ /* all we need is to make the tuple different in either the 0.0
+ * or -0.0 case from all others, just to avoid the "coercion".
+ */
+ if (*p==0 && p[sizeof(double)-1]==0)
+ t = PyTuple_Pack(3, o, o->ob_type, Py_None);
+ else
+ t = PyTuple_Pack(2, o, o->ob_type);
+ } else {
+ t = PyTuple_Pack(2, o, o->ob_type);
+ }
if (t == NULL)
return -1;
More information about the Python-checkins
mailing list