Issue 1678380: fix a bug identifying -0.0 and 0.0
This commit is contained in:
parent
78d50ccdf9
commit
2bebadfe51
|
@ -99,6 +99,27 @@ class IEEEFormatTestCase(unittest.TestCase):
|
||||||
('<f', LE_FLOAT_NAN)]:
|
('<f', LE_FLOAT_NAN)]:
|
||||||
struct.unpack(fmt, data)
|
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())
|
||||||
|
|
||||||
|
if float.__getformat__("double").startswith("IEEE"):
|
||||||
|
def test_underflow_sign(self):
|
||||||
|
import math
|
||||||
|
# check that -1e-1000 gives -0.0, not 0.0
|
||||||
|
self.assertEquals(math.atan2(-1e-1000, -1), math.atan2(-0.0, -1))
|
||||||
|
self.assertEquals(math.atan2(float('-1e-1000'), -1),
|
||||||
|
math.atan2(-0.0, -1))
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test_support.run_unittest(
|
test_support.run_unittest(
|
||||||
|
|
|
@ -12,6 +12,9 @@ What's New in Python 2.5.2c1?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #1678380: distinction between 0.0 and -0.0 was lost during constant
|
||||||
|
folding optimization. This was a regression from Python 2.4.
|
||||||
|
|
||||||
- Issue #1882: when compiling code from a string, encoding cookies in the
|
- Issue #1882: when compiling code from a string, encoding cookies in the
|
||||||
second line of code were not always recognized correctly.
|
second line of code were not always recognized correctly.
|
||||||
|
|
||||||
|
|
|
@ -1567,7 +1567,20 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
|
||||||
Py_ssize_t arg;
|
Py_ssize_t arg;
|
||||||
|
|
||||||
/* necessary to make sure types aren't coerced (e.g., int and long) */
|
/* 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)
|
if (t == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue