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

Skip to content

Commit a73ef2f

Browse files
committed
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 7b0d4a2 commit a73ef2f

1 file changed

Lines changed: 17 additions & 28 deletions

File tree

Python/compile.c

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -895,50 +895,39 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
895895
{
896896
PyObject *t, *v;
897897
Py_ssize_t arg;
898-
unsigned char *p;
899898
double d;
900899

901900
/* necessary to make sure types aren't coerced (e.g., int and long) */
902901
/* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */
903902
if (PyFloat_Check(o)) {
904903
d = PyFloat_AS_DOUBLE(o);
905-
p = (unsigned char*) &d;
906904
/* all we need is to make the tuple different in either the 0.0
907905
* or -0.0 case from all others, just to avoid the "coercion".
908906
*/
909-
if (*p==0 && p[sizeof(double)-1]==0)
907+
if (d == 0.0 && copysign(1.0, d) < 0.0)
910908
t = PyTuple_Pack(3, o, o->ob_type, Py_None);
911909
else
912910
t = PyTuple_Pack(2, o, o->ob_type);
913911
}
914912
else if (PyComplex_Check(o)) {
915913
Py_complex z;
916-
int real_part_zero, imag_part_zero;
917-
unsigned char *q;
918-
/* complex case is even messier: we need to make complex(x,
919-
0.) different from complex(x, -0.) and complex(0., y)
920-
different from complex(-0., y), for any x and y. In
921-
particular, all four complex zeros should be
922-
distinguished.*/
914+
int real_negzero, imag_negzero;
915+
/* For the complex case we must make complex(x, 0.)
916+
different from complex(x, -0.) and complex(0., y)
917+
different from complex(-0., y), for any x and y.
918+
All four complex zeros must be distinguished.*/
923919
z = PyComplex_AsCComplex(o);
924-
p = (unsigned char*) &(z.real);
925-
q = (unsigned char*) &(z.imag);
926-
/* all that matters here is that on IEEE platforms
927-
real_part_zero will be true if z.real == 0., and false if
928-
z.real == -0. In fact, real_part_zero will also be true
929-
for some other rarely occurring nonzero floats, but this
930-
doesn't matter. Similar comments apply to
931-
imag_part_zero. */
932-
real_part_zero = *p==0 && p[sizeof(double)-1]==0;
933-
imag_part_zero = *q==0 && q[sizeof(double)-1]==0;
934-
if (real_part_zero && imag_part_zero) {
935-
t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_True);
936-
}
937-
else if (real_part_zero && !imag_part_zero) {
938-
t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_False);
939-
}
940-
else if (!real_part_zero && imag_part_zero) {
941-
t = PyTuple_Pack(4, o, o->ob_type, Py_False, Py_True);
920+
real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
921+
imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
922+
if (real_negzero && imag_negzero) {
923+
t = PyTuple_Pack(5, o, o->ob_type,
924+
Py_None, Py_None, Py_None);
925+
}
926+
else if (imag_negzero) {
927+
t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None);
928+
}
929+
else if (real_negzero) {
930+
t = PyTuple_Pack(3, o, o->ob_type, Py_None);
942931
}
943932
else {
944933
t = PyTuple_Pack(2, o, o->ob_type);

0 commit comments

Comments
 (0)