Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 192ce61

Browse files
committed
Merged revisions 76577 via svnmerge from
svn+ssh://[email protected]/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://[email protected]/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 bcc63a8 commit 192ce61

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
@@ -909,51 +909,40 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
909909
{
910910
PyObject *t, *v;
911911
Py_ssize_t arg;
912-
unsigned char *p;
913912
double d;
914913

915914
/* necessary to make sure types aren't coerced (e.g., int and long) */
916915
/* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */
917916
if (PyFloat_Check(o)) {
918917
d = PyFloat_AS_DOUBLE(o);
919-
p = (unsigned char*) &d;
920918
/* all we need is to make the tuple different in either the 0.0
921919
* or -0.0 case from all others, just to avoid the "coercion".
922920
*/
923-
if (*p==0 && p[sizeof(double)-1]==0)
921+
if (d == 0.0 && copysign(1.0, d) < 0.0)
924922
t = PyTuple_Pack(3, o, o->ob_type, Py_None);
925923
else
926924
t = PyTuple_Pack(2, o, o->ob_type);
927925
}
928926
#ifndef WITHOUT_COMPLEX
929927
else if (PyComplex_Check(o)) {
930928
Py_complex z;
931-
int real_part_zero, imag_part_zero;
932-
unsigned char *q;
933-
/* complex case is even messier: we need to make complex(x,
934-
0.) different from complex(x, -0.) and complex(0., y)
935-
different from complex(-0., y), for any x and y. In
936-
particular, all four complex zeros should be
937-
distinguished.*/
929+
int real_negzero, imag_negzero;
930+
/* For the complex case we must make complex(x, 0.)
931+
different from complex(x, -0.) and complex(0., y)
932+
different from complex(-0., y), for any x and y.
933+
All four complex zeros must be distinguished.*/
938934
z = PyComplex_AsCComplex(o);
939-
p = (unsigned char*) &(z.real);
940-
q = (unsigned char*) &(z.imag);
941-
/* all that matters here is that on IEEE platforms
942-
real_part_zero will be true if z.real == 0., and false if
943-
z.real == -0. In fact, real_part_zero will also be true
944-
for some other rarely occurring nonzero floats, but this
945-
doesn't matter. Similar comments apply to
946-
imag_part_zero. */
947-
real_part_zero = *p==0 && p[sizeof(double)-1]==0;
948-
imag_part_zero = *q==0 && q[sizeof(double)-1]==0;
949-
if (real_part_zero && imag_part_zero) {
950-
t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_True);
935+
real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
936+
imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
937+
if (real_negzero && imag_negzero) {
938+
t = PyTuple_Pack(5, o, o->ob_type,
939+
Py_None, Py_None, Py_None);
951940
}
952-
else if (real_part_zero && !imag_part_zero) {
953-
t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_False);
941+
else if (imag_negzero) {
942+
t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None);
954943
}
955-
else if (!real_part_zero && imag_part_zero) {
956-
t = PyTuple_Pack(4, o, o->ob_type, Py_False, Py_True);
944+
else if (real_negzero) {
945+
t = PyTuple_Pack(3, o, o->ob_type, Py_None);
957946
}
958947
else {
959948
t = PyTuple_Pack(2, o, o->ob_type);

0 commit comments

Comments
 (0)