summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2009-11-28 16:39:12 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2009-11-28 16:39:12 (GMT)
commit192ce619416e4cba763b6b535b1c799e90504316 (patch)
treeb0133cee690a4aa97e4c774eb8edc30674a6ae75 /Python
parentbcc63a86a943b03e7472109cbf6d7f962f6b0b5a (diff)
downloadcpython-192ce619416e4cba763b6b535b1c799e90504316.zip
cpython-192ce619416e4cba763b6b535b1c799e90504316.tar.gz
cpython-192ce619416e4cba763b6b535b1c799e90504316.tar.bz2
Merged revisions 76577 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ................ r76577 | mark.dickinson | 2009-11-28 16:38:16 +0000 (Sat, 28 Nov 2009) | 12 lines Merged revisions 76575 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r76575 | mark.dickinson | 2009-11-28 16:32:27 +0000 (Sat, 28 Nov 2009) | 5 lines Issue #1678380: When distinguishing between -0.0 and 0.0 in compiler_add_o, use copysign instead of examining the first and last bytes of the double. The latter method fails for little-endian ARM, OABI, where doubles are little-endian but with the words swapped. ........ ................
Diffstat (limited to 'Python')
-rw-r--r--Python/compile.c41
1 files changed, 15 insertions, 26 deletions
diff --git a/Python/compile.c b/Python/compile.c
index 1a12b42..ab54208 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -909,18 +909,16 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
{
PyObject *t, *v;
Py_ssize_t arg;
- unsigned char *p;
double d;
/* 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 */
if (PyFloat_Check(o)) {
d = PyFloat_AS_DOUBLE(o);
- 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)
+ if (d == 0.0 && copysign(1.0, d) < 0.0)
t = PyTuple_Pack(3, o, o->ob_type, Py_None);
else
t = PyTuple_Pack(2, o, o->ob_type);
@@ -928,32 +926,23 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
#ifndef WITHOUT_COMPLEX
else if (PyComplex_Check(o)) {
Py_complex z;
- int real_part_zero, imag_part_zero;
- unsigned char *q;
- /* 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.*/
+ int real_negzero, imag_negzero;
+ /* For the complex case we must make complex(x, 0.)
+ different from complex(x, -0.) and complex(0., y)
+ different from complex(-0., y), for any x and y.
+ All four complex zeros must 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);
+ real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
+ imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
+ if (real_negzero && imag_negzero) {
+ t = PyTuple_Pack(5, o, o->ob_type,
+ Py_None, Py_None, Py_None);
}
- else if (real_part_zero && !imag_part_zero) {
- t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_False);
+ else if (imag_negzero) {
+ t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None);
}
- else if (!real_part_zero && imag_part_zero) {
- t = PyTuple_Pack(4, o, o->ob_type, Py_False, Py_True);
+ else if (real_negzero) {
+ t = PyTuple_Pack(3, o, o->ob_type, Py_None);
}
else {
t = PyTuple_Pack(2, o, o->ob_type);