diff options
-rwxr-xr-x | Lib/test/test_cmath.py | 113 |
1 files changed, 50 insertions, 63 deletions
diff --git a/Lib/test/test_cmath.py b/Lib/test/test_cmath.py index 2ab5a78..d60d2f0 100755 --- a/Lib/test/test_cmath.py +++ b/Lib/test/test_cmath.py @@ -46,37 +46,6 @@ complex_nans = [complex(x, y) for x, y in [ (INF, NAN) ]] -def almostEqualF(a, b, rel_err=2e-15, abs_err = 5e-323): - """Determine whether floating-point values a and b are equal to within - a (small) rounding error. The default values for rel_err and - abs_err are chosen to be suitable for platforms where a float is - represented by an IEEE 754 double. They allow an error of between - 9 and 19 ulps.""" - - # special values testing - if math.isnan(a): - return math.isnan(b) - if math.isinf(a): - return a == b - - # if both a and b are zero, check whether they have the same sign - # (in theory there are examples where it would be legitimate for a - # and b to have opposite signs; in practice these hardly ever - # occur). - if not a and not b: - return math.copysign(1., a) == math.copysign(1., b) - - # if a-b overflows, or b is infinite, return False. Again, in - # theory there are examples where a is within a few ulps of the - # max representable float, and then b could legitimately be - # infinite. In practice these examples are rare. - try: - absolute_error = abs(b-a) - except OverflowError: - return False - else: - return absolute_error <= max(abs_err, rel_err * abs(a)) - class CMathTests(unittest.TestCase): # list of all functions in cmath test_functions = [getattr(cmath, fname) for fname in [ @@ -93,47 +62,63 @@ class CMathTests(unittest.TestCase): def tearDown(self): self.test_values.close() - def rAssertAlmostEqual(self, a, b, rel_err = 2e-15, abs_err = 5e-323): - """Check that two floating-point numbers are almost equal.""" + def rAssertAlmostEqual(self, a, b, rel_err = 2e-15, abs_err = 5e-323, + msg=None): + """Fail if the two floating-point numbers are not almost equal. + + Determine whether floating-point values a and b are equal to within + a (small) rounding error. The default values for rel_err and + abs_err are chosen to be suitable for platforms where a float is + represented by an IEEE 754 double. They allow an error of between + 9 and 19 ulps. + """ # special values testing if math.isnan(a): if math.isnan(b): return - self.fail("%s should be nan" % repr(b)) + self.fail(msg or '{!r} should be nan'.format(b)) if math.isinf(a): if a == b: return - self.fail("finite result where infinity excpected: " - "expected %s, got %s" % (repr(a), repr(b))) + self.fail(msg or 'finite result where infinity expected: ' + 'expected {!r}, got {!r}'.format(a, b)) + # if both a and b are zero, check whether they have the same sign + # (in theory there are examples where it would be legitimate for a + # and b to have opposite signs; in practice these hardly ever + # occur). if not a and not b: - if math.atan2(a, -1.) != math.atan2(b, -1.): - self.fail("zero has wrong sign: expected %s, got %s" % - (repr(a), repr(b))) - - # test passes if either the absolute error or the relative - # error is sufficiently small. The defaults amount to an - # error of between 9 ulps and 19 ulps on an IEEE-754 compliant - # machine. - + if math.copysign(1., a) != math.copysign(1., b): + self.fail(msg or 'zero has wrong sign: expected {!r}, ' + 'got {!r}'.format(a, b)) + + # if a-b overflows, or b is infinite, return False. Again, in + # theory there are examples where a is within a few ulps of the + # max representable float, and then b could legitimately be + # infinite. In practice these examples are rare. try: absolute_error = abs(b-a) except OverflowError: pass else: + # test passes if either the absolute error or the relative + # error is sufficiently small. The defaults amount to an + # error of between 9 ulps and 19 ulps on an IEEE-754 compliant + # machine. if absolute_error <= max(abs_err, rel_err * abs(a)): return - self.fail("%s and %s are not sufficiently close" % (repr(a), repr(b))) + self.fail(msg or + '{!r} and {!r} are not sufficiently close'.format(a, b)) def test_constants(self): e_expected = 2.71828182845904523536 pi_expected = 3.14159265358979323846 self.assertAlmostEqual(cmath.pi, pi_expected, places=9, - msg="cmath.pi is %s; should be %s" % (cmath.pi, pi_expected)) + msg="cmath.pi is {}; should be {}".format(cmath.pi, pi_expected)) self.assertAlmostEqual(cmath.e, e_expected, places=9, - msg="cmath.e is %s; should be %s" % (cmath.e, e_expected)) + msg="cmath.e is {}; should be {}".format(cmath.e, e_expected)) def test_user_object(self): # Test automatic calling of __complex__ and __float__ by cmath @@ -323,8 +308,8 @@ class CMathTests(unittest.TestCase): except ValueError: continue else: - test_str = "%s: %s(complex(%r, %r))" % (id, fn, ar, ai) - self.fail('ValueError not raised in test %s' % test_str) + self.fail('ValueError not raised in test ' + '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai)) if 'overflow' in flags: try: @@ -332,8 +317,8 @@ class CMathTests(unittest.TestCase): except OverflowError: continue else: - test_str = "%s: %s(complex(%r, %r))" % (id, fn, ar, ai) - self.fail('OverflowError not raised in test %s' % test_str) + self.fail('OverflowError not raised in test ' + '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai)) actual = function(arg) @@ -351,17 +336,19 @@ class CMathTests(unittest.TestCase): else: real_abs_err = 5e-323 - if not (almostEqualF(expected.real, actual.real, - abs_err = real_abs_err) and - almostEqualF(expected.imag, actual.imag)): - error_message = ( - "%s: %s(complex(%r, %r))\n" % (id, fn, ar, ai) + - "Expected: complex(%r, %r)\n" % - (expected.real, expected.imag) + - "Received: complex(%r, %r)\n" % - (actual.real, actual.imag) + - "Received value insufficiently close to expected value.") - self.fail(error_message) + error_message = ( + '{}: {}(complex({!r}, {!r}))\n' + 'Expected: complex({!r}, {!r})\n' + 'Received: complex({!r}, {!r})\n' + 'Received value insufficiently close to expected value.' + ).format(id, fn, ar, ai, + expected.real, expected.imag, + actual.real, actual.imag) + self.rAssertAlmostEqual(expected.real, actual.real, + abs_err=real_abs_err, + msg=error_message) + self.rAssertAlmostEqual(expected.imag, actual.imag, + msg=error_message) def assertCISEqual(self, a, b): eps = 1E-7 |