[Python-checkins] r76575 - python/trunk/Python/compile.c

mark.dickinson python-checkins at python.org
Sat Nov 28 17:32:27 CET 2009


Author: mark.dickinson
Date: Sat Nov 28 17:32:27 2009
New Revision: 76575

Log:
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.


Modified:
   python/trunk/Python/compile.c

Modified: python/trunk/Python/compile.c
==============================================================================
--- python/trunk/Python/compile.c	(original)
+++ python/trunk/Python/compile.c	Sat Nov 28 17:32:27 2009
@@ -910,18 +910,16 @@
 {
 	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);
@@ -929,32 +927,23 @@
 #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);


More information about the Python-checkins mailing list