mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	Issue #1678380. Fix a bug that identifies 0j and -0j when they appear
in the same code unit. The fix is essentially the same as the fix for a previous bug identifying 0. and -0.
This commit is contained in:
		
							parent
							
								
									2df20a3e08
								
							
						
					
					
						commit
						105be7725b
					
				
					 3 changed files with 57 additions and 12 deletions
				
			
		|  | @ -359,6 +359,13 @@ def test_file(self): | ||||||
|             except (OSError, IOError): |             except (OSError, IOError): | ||||||
|                 pass |                 pass | ||||||
| 
 | 
 | ||||||
|  |     if float.__getformat__("double").startswith("IEEE"): | ||||||
|  |         def test_plus_minus_0j(self): | ||||||
|  |             # test that -0j and 0j literals are not identified | ||||||
|  |             z1, z2 = 0j, -0j | ||||||
|  |             self.assertEquals(atan2(z1.imag, -1.), atan2(0., -1.)) | ||||||
|  |             self.assertEquals(atan2(z2.imag, -1.), atan2(-0., -1.)) | ||||||
|  | 
 | ||||||
| def test_main(): | def test_main(): | ||||||
|     test_support.run_unittest(ComplexTest) |     test_support.run_unittest(ComplexTest) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1? | ||||||
| Core and builtins | Core and builtins | ||||||
| ----------------- | ----------------- | ||||||
| 
 | 
 | ||||||
|  | - Issue #1678380: Fix a bug that identifies 0j and -0j when they appear | ||||||
|  |   in the same code unit. | ||||||
|  | 
 | ||||||
| - Patch #1970 by Antoine Pitrou: Speedup unicode whitespace and linebreak | - Patch #1970 by Antoine Pitrou: Speedup unicode whitespace and linebreak | ||||||
|   detection |   detection | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -907,12 +907,16 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) | ||||||
| { | { | ||||||
| 	PyObject *t, *v; | 	PyObject *t, *v; | ||||||
| 	Py_ssize_t arg; | 	Py_ssize_t arg; | ||||||
|  | 	unsigned char *p, *q; | ||||||
|  | 	Py_complex z; | ||||||
|  | 	double d; | ||||||
|  | 	int real_part_zero, imag_part_zero; | ||||||
| 
 | 
 | ||||||
| 	/* necessary to make sure types aren't coerced (e.g., int and long) */ | 	/* 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 */ |         /* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */ | ||||||
|         if (PyFloat_Check(o)) { |         if (PyFloat_Check(o)) { | ||||||
|             double d = PyFloat_AS_DOUBLE(o); | 		d = PyFloat_AS_DOUBLE(o); | ||||||
|             unsigned char* p = (unsigned char*) &d; | 		p = (unsigned char*) &d; | ||||||
| 		/* all we need is to make the tuple different in either the 0.0
 | 		/* 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". | 		 * or -0.0 case from all others, just to avoid the "coercion". | ||||||
| 		 */ | 		 */ | ||||||
|  | @ -920,7 +924,38 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) | ||||||
| 			t = PyTuple_Pack(3, o, o->ob_type, Py_None); | 			t = PyTuple_Pack(3, o, o->ob_type, Py_None); | ||||||
| 		else | 		else | ||||||
| 			t = PyTuple_Pack(2, o, o->ob_type); | 			t = PyTuple_Pack(2, o, o->ob_type); | ||||||
|         } else { | 	} | ||||||
|  | 	else if (PyComplex_Check(o)) { | ||||||
|  | 		/* 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.*/ | ||||||
|  | 		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); | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			t = PyTuple_Pack(2, o, o->ob_type); | ||||||
|  | 		} | ||||||
|  |         } | ||||||
|  | 	else { | ||||||
| 		t = PyTuple_Pack(2, o, o->ob_type); | 		t = PyTuple_Pack(2, o, o->ob_type); | ||||||
|         } |         } | ||||||
| 	if (t == NULL) | 	if (t == NULL) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Mark Dickinson
						Mark Dickinson