[Python-checkins] r60875 - in python/branches/trunk-math: Lib/test/test_complex.py Objects/complexobject.c

christian.heimes python-checkins at python.org
Sun Feb 17 14:34:42 CET 2008


Author: christian.heimes
Date: Sun Feb 17 14:34:41 2008
New Revision: 60875

Modified:
   python/branches/trunk-math/Lib/test/test_complex.py
   python/branches/trunk-math/Objects/complexobject.c
Log:
Better algorithm for complex division by zero.

Modified: python/branches/trunk-math/Lib/test/test_complex.py
==============================================================================
--- python/branches/trunk-math/Lib/test/test_complex.py	(original)
+++ python/branches/trunk-math/Lib/test/test_complex.py	Sun Feb 17 14:34:41 2008
@@ -54,14 +54,16 @@
         self.assert_(a is b)
 
     def assertInf(self, a, real_sign=1, imag_sign=1):
-        self.assert_(isinf(a.real), a)
-        self.assertEqual(copysign(1, a.real), real_sign)
-        self.assert_(isinf(a.imag), a)
-        self.assertEqual(copysign(1, a.imag), imag_sign)
-
-    def assertNan(self, a):
-        self.assert_(isnan(a.real), a)
-        self.assert_(isnan(a.imag), a)
+        if not real_sign:
+            self.assert_(isnan(a.real), a)
+        else:
+            self.assert_(isinf(a.real), a)
+            self.assertEqual(copysign(1, a.real), real_sign)
+        if not imag_sign:
+            self.assert_(isnan(a.imag), a)
+        else:
+            self.assert_(isinf(a.imag), a)
+            self.assertEqual(copysign(1, a.imag), imag_sign)
 
     def check_div(self, x, y):
         """Compute complex z=x*y, and check that z/x==y and z/y==x."""
@@ -112,15 +114,16 @@
 
     def test_div_ieee754(self):
         with ieee754():
-            self.assertInf(complex(1., 0) / complex(0.), 1, 1)
-            self.assertInf(complex(-1., 0) / complex(0.), 1, 1)
-            self.assertInf(complex(0, 1.) / complex(0.), 1, 1)
-            self.assertInf(complex(0, -1.) / complex(0.), 1, -1)
+            self.assertInf(complex(1., 0) / complex(0.), 1, 0)
+            self.assertInf(complex(-1., 0) / complex(0.), -1, 0)
+            self.assertInf(complex(-1., 0) / complex(-0.), 1, 0)
+            self.assertInf(complex(0, 1.) / complex(0.), 0, 1)
+            self.assertInf(complex(0, -1.) / complex(0.), 0, -1)
             self.assertInf(complex(1., 1.) / complex(0.), 1, 1)
             self.assertInf(complex(1., -1.) / complex(0.), 1, -1)
-            self.assertInf(complex(-1., 1.) / complex(0.), 1, 1)
-            self.assertInf(complex(-1., -1.) / complex(0.), -1, 1)
-            self.assertNan(complex(0.) / complex(0.))
+            self.assertInf(complex(-1., 1.) / complex(0.), -1, 1)
+            self.assertInf(complex(-1., -1.) / complex(0.), -1, -1)
+            self.assertInf(complex(0.) / complex(0.), 0, 0)
 
     def test_coerce(self):
         self.assertRaises(OverflowError, complex.__coerce__, 1+1j, 1L<<10000)

Modified: python/branches/trunk-math/Objects/complexobject.c
==============================================================================
--- python/branches/trunk-math/Objects/complexobject.c	(original)
+++ python/branches/trunk-math/Objects/complexobject.c	Sun Feb 17 14:34:41 2008
@@ -125,23 +125,16 @@
 {
 	/* IEEE 754 style division */
 	if (b.real == 0. && b.imag == 0.) {
+		/* Complex division by zero
+		 * - division of a complex w/o an imaginary part behaves like
+		 *   float division: (x+0j)/(0+0j) == x/0
+		 * - (0+0j)/(0+0j) results in NAN
+		 * - for the remaining cases it's trying to do something
+		 *   sensible while keeping the invariant abs(c/0) == inf
+		 */
 		Py_complex quot;
-		if (a.real == 0. && a.imag == 0.) {
-			/* 0./0. */
-			quot.real = Py_NAN;
-			quot.imag = Py_NAN;
-		}
-		else {
-			float re, im;
-			/* the outcome is inexact but we care only about the
-			 * sign bits
-			 * (a+ib)/(c+id) = (ac+bd)/(c2+d2) + i(bc-ad)/(c2+d2)
-			 */
-			re = a.real * b.real + a.imag * b.imag;
-			im = a.imag * b.real - a.real * b.imag;
-			quot.real = copysign(Py_HUGE_VAL, re);
-			quot.imag = copysign(Py_HUGE_VAL, im);
-		}
+		quot.real = copysign(Py_HUGE_VAL, b.real) * a.real;
+		quot.imag = copysign(Py_HUGE_VAL, b.imag) * a.imag;
 		return quot;
 	}
 	return c_quot(a, b);


More information about the Python-checkins mailing list