Issue #1678380. Fix a bug that identifies 0j and -0j when they appear
in the same code unit. The fix is essentially the same as the fix for a previous bug identifying 0. and -0.
This commit is contained in:
parent
2df20a3e08
commit
105be7725b
|
@ -359,6 +359,13 @@ class ComplexTest(unittest.TestCase):
|
||||||
except (OSError, IOError):
|
except (OSError, IOError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if float.__getformat__("double").startswith("IEEE"):
|
||||||
|
def test_plus_minus_0j(self):
|
||||||
|
# test that -0j and 0j literals are not identified
|
||||||
|
z1, z2 = 0j, -0j
|
||||||
|
self.assertEquals(atan2(z1.imag, -1.), atan2(0., -1.))
|
||||||
|
self.assertEquals(atan2(z2.imag, -1.), atan2(-0., -1.))
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test_support.run_unittest(ComplexTest)
|
test_support.run_unittest(ComplexTest)
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #1678380: Fix a bug that identifies 0j and -0j when they appear
|
||||||
|
in the same code unit.
|
||||||
|
|
||||||
- Patch #1970 by Antoine Pitrou: Speedup unicode whitespace and linebreak
|
- Patch #1970 by Antoine Pitrou: Speedup unicode whitespace and linebreak
|
||||||
detection
|
detection
|
||||||
|
|
||||||
|
|
|
@ -907,24 +907,59 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
|
||||||
{
|
{
|
||||||
PyObject *t, *v;
|
PyObject *t, *v;
|
||||||
Py_ssize_t arg;
|
Py_ssize_t arg;
|
||||||
|
unsigned char *p, *q;
|
||||||
|
Py_complex z;
|
||||||
|
double d;
|
||||||
|
int real_part_zero, imag_part_zero;
|
||||||
|
|
||||||
/* 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) */
|
||||||
/* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */
|
/* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */
|
||||||
if (PyFloat_Check(o)) {
|
if (PyFloat_Check(o)) {
|
||||||
double d = PyFloat_AS_DOUBLE(o);
|
d = PyFloat_AS_DOUBLE(o);
|
||||||
unsigned char* p = (unsigned char*) &d;
|
p = (unsigned char*) &d;
|
||||||
/* all we need is to make the tuple different in either the 0.0
|
/* 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".
|
* or -0.0 case from all others, just to avoid the "coercion".
|
||||||
*/
|
*/
|
||||||
if (*p==0 && p[sizeof(double)-1]==0)
|
if (*p==0 && p[sizeof(double)-1]==0)
|
||||||
t = PyTuple_Pack(3, o, o->ob_type, Py_None);
|
t = PyTuple_Pack(3, o, o->ob_type, Py_None);
|
||||||
else
|
else
|
||||||
t = PyTuple_Pack(2, o, o->ob_type);
|
t = PyTuple_Pack(2, o, o->ob_type);
|
||||||
} else {
|
}
|
||||||
t = PyTuple_Pack(2, o, o->ob_type);
|
else if (PyComplex_Check(o)) {
|
||||||
|
/* complex case is even messier: we need to make complex(x,
|
||||||
|
0.) different from complex(x, -0.) and complex(0., y)
|
||||||
|
different from complex(-0., y), for any x and y. In
|
||||||
|
particular, all four complex zeros should be
|
||||||
|
distinguished.*/
|
||||||
|
z = PyComplex_AsCComplex(o);
|
||||||
|
p = (unsigned char*) &(z.real);
|
||||||
|
q = (unsigned char*) &(z.imag);
|
||||||
|
/* all that matters here is that on IEEE platforms
|
||||||
|
real_part_zero will be true if z.real == 0., and false if
|
||||||
|
z.real == -0. In fact, real_part_zero will also be true
|
||||||
|
for some other rarely occurring nonzero floats, but this
|
||||||
|
doesn't matter. Similar comments apply to
|
||||||
|
imag_part_zero. */
|
||||||
|
real_part_zero = *p==0 && p[sizeof(double)-1]==0;
|
||||||
|
imag_part_zero = *q==0 && q[sizeof(double)-1]==0;
|
||||||
|
if (real_part_zero && imag_part_zero) {
|
||||||
|
t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_True);
|
||||||
|
}
|
||||||
|
else if (real_part_zero && !imag_part_zero) {
|
||||||
|
t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_False);
|
||||||
|
}
|
||||||
|
else if (!real_part_zero && imag_part_zero) {
|
||||||
|
t = PyTuple_Pack(4, o, o->ob_type, Py_False, Py_True);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
v = PyDict_GetItem(dict, t);
|
v = PyDict_GetItem(dict, t);
|
||||||
if (!v) {
|
if (!v) {
|
||||||
|
|
Loading…
Reference in New Issue