diff options
| author | Mark Dickinson <dickinsm@gmail.com> | 2009-11-28 16:38:16 (GMT) | 
|---|---|---|
| committer | Mark Dickinson <dickinsm@gmail.com> | 2009-11-28 16:38:16 (GMT) | 
| commit | a73ef2f979e4439d76d59a4f10bd919ee376ff1d (patch) | |
| tree | 607f7c86da3bffaae6c6c72120842bb9c8737868 /Python/compile.c | |
| parent | 7b0d4a238f2a69747ed570f8bfb51fb31315eba9 (diff) | |
| download | cpython-a73ef2f979e4439d76d59a4f10bd919ee376ff1d.zip cpython-a73ef2f979e4439d76d59a4f10bd919ee376ff1d.tar.gz cpython-a73ef2f979e4439d76d59a4f10bd919ee376ff1d.tar.bz2  | |
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/compile.c')
| -rw-r--r-- | Python/compile.c | 45 | 
1 files changed, 17 insertions, 28 deletions
diff --git a/Python/compile.c b/Python/compile.c index d8fb47b..2c58d44 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -895,50 +895,39 @@ 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);  	}  	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); -		} -		else if (real_part_zero && !imag_part_zero) { -			t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_False); -		} -		else if (!real_part_zero && imag_part_zero) { -			t = PyTuple_Pack(4, o, o->ob_type, Py_False, 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 (imag_negzero) { +			t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None); +		} +		else if (real_negzero) { +			t = PyTuple_Pack(3, o, o->ob_type, Py_None);  		}  		else {  			t = PyTuple_Pack(2, o, o->ob_type);  | 
