Skip to content

Commit 48a522d

Browse files
committed
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. ........
1 parent 22919aa commit 48a522d

1 file changed

Lines changed: 15 additions & 26 deletions

File tree

‎Python/compile.c‎

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -922,51 +922,40 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
922922
{
923923
PyObject *t, *v;
924924
Py_ssize_t arg;
925-
unsigned char *p;
926925
double d;
927926

928927
/* necessary to make sure types aren't coerced (e.g., int and long) */
929928
/* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */
930929
if (PyFloat_Check(o)) {
931930
d = PyFloat_AS_DOUBLE(o);
932-
p = (unsigned char*) &d;
933931
/* all we need is to make the tuple different in either the 0.0
934932
* or -0.0 case from all others, just to avoid the "coercion".
935933
*/
936-
if (*p==0 && p[sizeof(double)-1]==0)
934+
if (d == 0.0 && copysign(1.0, d) < 0.0)
937935
t = PyTuple_Pack(3, o, o->ob_type, Py_None);
938936
else
939937
t = PyTuple_Pack(2, o, o->ob_type);
940938
}
941939
#ifndef WITHOUT_COMPLEX
942940
else if (PyComplex_Check(o)) {
943941
Py_complex z;
944-
int real_part_zero, imag_part_zero;
945-
unsigned char *q;
946-
/* complex case is even messier: we need to make complex(x,
947-
0.) different from complex(x, -0.) and complex(0., y)
948-
different from complex(-0., y), for any x and y. In
949-
particular, all four complex zeros should be
950-
distinguished.*/
942+
int real_negzero, imag_negzero;
943+
/* For the complex case we must make complex(x, 0.)
944+
different from complex(x, -0.) and complex(0., y)
945+
different from complex(-0., y), for any x and y.
946+
All four complex zeros must be distinguished.*/
951947
z = PyComplex_AsCComplex(o);
952-
p = (unsigned char*) &(z.real);
953-
q = (unsigned char*) &(z.imag);
954-
/* all that matters here is that on IEEE platforms
955-
real_part_zero will be true if z.real == 0., and false if
956-
z.real == -0. In fact, real_part_zero will also be true
957-
for some other rarely occurring nonzero floats, but this
958-
doesn't matter. Similar comments apply to
959-
imag_part_zero. */
960-
real_part_zero = *p==0 && p[sizeof(double)-1]==0;
961-
imag_part_zero = *q==0 && q[sizeof(double)-1]==0;
962-
if (real_part_zero && imag_part_zero) {
963-
t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_True);
948+
real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
949+
imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
950+
if (real_negzero && imag_negzero) {
951+
t = PyTuple_Pack(5, o, o->ob_type,
952+
Py_None, Py_None, Py_None);
964953
}
965-
else if (real_part_zero && !imag_part_zero) {
966-
t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_False);
954+
else if (imag_negzero) {
955+
t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None);
967956
}
968-
else if (!real_part_zero && imag_part_zero) {
969-
t = PyTuple_Pack(4, o, o->ob_type, Py_False, Py_True);
957+
else if (real_negzero) {
958+
t = PyTuple_Pack(3, o, o->ob_type, Py_None);
970959
}
971960
else {
972961
t = PyTuple_Pack(2, o, o->ob_type);

0 commit comments

Comments
 (0)