[Python-checkins] r60816 - in python/branches/trunk-math: Lib/test/test_cmath.py Objects/complexobject.c
mark.dickinson
python-checkins at python.org
Thu Feb 14 22:17:23 CET 2008
Author: mark.dickinson
Date: Thu Feb 14 22:17:22 2008
New Revision: 60816
Modified:
python/branches/trunk-math/Lib/test/test_cmath.py
python/branches/trunk-math/Objects/complexobject.c
Log:
Add special-value tests for phase and complex absolute value, and fix
abs(complex_number) so that it raises OverflowError instead of returning
inf on overflow.
Modified: python/branches/trunk-math/Lib/test/test_cmath.py
==============================================================================
--- python/branches/trunk-math/Lib/test/test_cmath.py (original)
+++ python/branches/trunk-math/Lib/test/test_cmath.py Thu Feb 14 22:17:22 2008
@@ -8,6 +8,44 @@
INF = float('inf')
NAN = float('nan')
+complex_zeros = [complex(x, y) for x in [0.0, -0.0] for y in [0.0, -0.0]]
+complex_infinities = [complex(x, y) for x, y in [
+ (INF, 0.0), # 1st quadrant
+ (INF, 2.3),
+ (INF, INF),
+ (2.3, INF),
+ (0.0, INF),
+ (-0.0, INF), # 2nd quadrant
+ (-2.3, INF),
+ (-INF, INF),
+ (-INF, 2.3),
+ (-INF, 0.0),
+ (-INF, -0.0), # 3rd quadrant
+ (-INF, -2.3),
+ (-INF, -INF),
+ (-2.3, -INF),
+ (-0.0, -INF),
+ (0.0, -INF), # 4th quadrant
+ (2.3, -INF),
+ (INF, -INF),
+ (INF, -2.3),
+ (INF, -0.0)
+ ]]
+complex_nans = [complex(x, y) for x, y in [
+ (NAN, -INF),
+ (NAN, -2.3),
+ (NAN, -0.0),
+ (NAN, 0.0),
+ (NAN, 2.3),
+ (NAN, INF),
+ (-INF, NAN),
+ (-2.3, NAN),
+ (-0.0, NAN),
+ (0.0, NAN),
+ (2.3, NAN),
+ (INF, NAN)
+ ]]
+
class CMathTests(unittest.TestCase):
# list of all functions in cmath
test_functions = [getattr(cmath, fname) for fname in [
@@ -273,6 +311,66 @@
self.assertAlmostEqual(phase(1j), pi/2)
self.assertAlmostEqual(phase(-1j), -pi/2)
+ # zeros
+ self.assertEqual(phase(complex(0.0, 0.0)), 0.0)
+ self.assertEqual(phase(complex(0.0, -0.0)), -0.0)
+ self.assertEqual(phase(complex(-0.0, 0.0)), pi)
+ self.assertEqual(phase(complex(-0.0, -0.0)), -pi)
+
+ # infinities
+ self.assertAlmostEqual(phase(complex(-INF, -0.0)), -pi)
+ self.assertAlmostEqual(phase(complex(-INF, -2.3)), -pi)
+ self.assertAlmostEqual(phase(complex(-INF, -INF)), -0.75*pi)
+ self.assertAlmostEqual(phase(complex(-2.3, -INF)), -pi/2)
+ self.assertAlmostEqual(phase(complex(-0.0, -INF)), -pi/2)
+ self.assertAlmostEqual(phase(complex(0.0, -INF)), -pi/2)
+ self.assertAlmostEqual(phase(complex(2.3, -INF)), -pi/2)
+ self.assertAlmostEqual(phase(complex(INF, -INF)), -pi/4)
+ self.assertEqual(phase(complex(INF, -2.3)), -0.0)
+ self.assertEqual(phase(complex(INF, -0.0)), -0.0)
+ self.assertEqual(phase(complex(INF, 0.0)), 0.0)
+ self.assertEqual(phase(complex(INF, 2.3)), 0.0)
+ self.assertAlmostEqual(phase(complex(INF, INF)), pi/4)
+ self.assertAlmostEqual(phase(complex(2.3, INF)), pi/2)
+ self.assertAlmostEqual(phase(complex(0.0, INF)), pi/2)
+ self.assertAlmostEqual(phase(complex(-0.0, INF)), pi/2)
+ self.assertAlmostEqual(phase(complex(-2.3, INF)), pi/2)
+ self.assertAlmostEqual(phase(complex(-INF, INF)), 0.75*pi)
+ self.assertAlmostEqual(phase(complex(-INF, 2.3)), pi)
+ self.assertAlmostEqual(phase(complex(-INF, 0.0)), pi)
+
+ # real or imaginary part NaN
+ for z in complex_nans:
+ self.assert_(math.isnan(phase(z)))
+
+ def test_abs(self):
+ # zeros
+ for z in complex_zeros:
+ self.assertEqual(abs(z), 0.0)
+
+ # infinities
+ for z in complex_infinities:
+ self.assertEqual(abs(z), INF)
+
+ # real or imaginary part NaN
+ self.assertEqual(abs(complex(NAN, -INF)), INF)
+ self.assert_(math.isnan(abs(complex(NAN, -2.3))))
+ self.assert_(math.isnan(abs(complex(NAN, -0.0))))
+ self.assert_(math.isnan(abs(complex(NAN, 0.0))))
+ self.assert_(math.isnan(abs(complex(NAN, 2.3))))
+ self.assertEqual(abs(complex(NAN, INF)), INF)
+ self.assertEqual(abs(complex(-INF, NAN)), INF)
+ self.assert_(math.isnan(abs(complex(-2.3, NAN))))
+ self.assert_(math.isnan(abs(complex(-0.0, NAN))))
+ self.assert_(math.isnan(abs(complex(0.0, NAN))))
+ self.assert_(math.isnan(abs(complex(2.3, NAN))))
+ self.assertEqual(abs(complex(INF, NAN)), INF)
+ self.assert_(math.isnan(abs(complex(NAN, NAN))))
+
+ # result overflows
+ if float.__getformat__("double").startswith("IEEE"):
+ self.assertRaises(OverflowError, abs, complex(1.4e308, 1.4e308))
+
def assertCEqual(self, a, b):
eps = 1E-7
if abs(a.real - b[0]) > eps or abs(a.imag - b[1]) > eps:
Modified: python/branches/trunk-math/Objects/complexobject.c
==============================================================================
--- python/branches/trunk-math/Objects/complexobject.c (original)
+++ python/branches/trunk-math/Objects/complexobject.c Thu Feb 14 22:17:22 2008
@@ -621,6 +621,16 @@
PyFPE_START_PROTECT("complex_abs", return 0)
result = hypot(v->cval.real,v->cval.imag);
PyFPE_END_PROTECT(result)
+
+ /* an infinite result from finite operands should
+ result in OverflowError */
+ if (Py_IS_INFINITY(result) &&
+ Py_IS_FINITE(v->cval.real) &&
+ Py_IS_FINITE(v->cval.imag)) {
+ PyErr_SetString(PyExc_OverflowError,
+ "absolute value too large");
+ return NULL;
+ }
return PyFloat_FromDouble(result);
}
More information about the Python-checkins
mailing list