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.
This commit is contained in:
parent
89e975fc74
commit
d8672aa8a4
|
@ -81,6 +81,7 @@ class UnknownFormatTestCase(unittest.TestCase):
|
|||
# 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 @@ class IEEEFormatTestCase(unittest.TestCase):
|
|||
('<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(
|
||||
|
|
|
@ -907,7 +907,20 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
|
|||
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue