diff options
author | Raymond Hettinger <rhettinger@users.noreply.github.com> | 2018-07-28 14:48:04 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-28 14:48:04 (GMT) |
commit | c6dabe37e3c4d449562182b044184d1756bea037 (patch) | |
tree | bbb89623d68962192e810c5327ae98ff28084025 /Lib | |
parent | 50326927465c3f5c6c0168fc43310c8e97db0a47 (diff) | |
download | cpython-c6dabe37e3c4d449562182b044184d1756bea037.zip cpython-c6dabe37e3c4d449562182b044184d1756bea037.tar.gz cpython-c6dabe37e3c4d449562182b044184d1756bea037.tar.bz2 |
bpo-33089: Multidimensional math.hypot() (GH-8474)
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_math.py | 76 |
1 files changed, 66 insertions, 10 deletions
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 44785d3..4843899 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -16,6 +16,7 @@ NAN = float('nan') INF = float('inf') NINF = float('-inf') FLOAT_MAX = sys.float_info.max +FLOAT_MIN = sys.float_info.min # detect evidence of double-rounding: fsum is not always correctly # rounded on machines that suffer from double rounding. @@ -720,16 +721,71 @@ class MathTests(unittest.TestCase): self.assertEqual(gcd(MyIndexable(120), MyIndexable(84)), 12) def testHypot(self): - self.assertRaises(TypeError, math.hypot) - self.ftest('hypot(0,0)', math.hypot(0,0), 0) - self.ftest('hypot(3,4)', math.hypot(3,4), 5) - self.assertEqual(math.hypot(NAN, INF), INF) - self.assertEqual(math.hypot(INF, NAN), INF) - self.assertEqual(math.hypot(NAN, NINF), INF) - self.assertEqual(math.hypot(NINF, NAN), INF) - self.assertRaises(OverflowError, math.hypot, FLOAT_MAX, FLOAT_MAX) - self.assertTrue(math.isnan(math.hypot(1.0, NAN))) - self.assertTrue(math.isnan(math.hypot(NAN, -2.0))) + from decimal import Decimal + from fractions import Fraction + + hypot = math.hypot + + # Test different numbers of arguments (from zero to five) + # against a straightforward pure python implementation + args = math.e, math.pi, math.sqrt(2.0), math.gamma(3.5), math.sin(2.1) + for i in range(len(args)+1): + self.assertAlmostEqual( + hypot(*args[:i]), + math.sqrt(sum(s**2 for s in args[:i])) + ) + + # Test allowable types (those with __float__) + self.assertEqual(hypot(12.0, 5.0), 13.0) + self.assertEqual(hypot(12, 5), 13) + self.assertEqual(hypot(Decimal(12), Decimal(5)), 13) + self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32)) + self.assertEqual(hypot(bool(1), bool(0), bool(1), bool(1)), math.sqrt(3)) + + # Test corner cases + self.assertEqual(hypot(0.0, 0.0), 0.0) # Max input is zero + self.assertEqual(hypot(-10.5), 10.5) # Negative input + self.assertEqual(hypot(), 0.0) # Negative input + self.assertEqual(1.0, + math.copysign(1.0, hypot(-0.0)) # Convert negative zero to positive zero + ) + + # Test handling of bad arguments + with self.assertRaises(TypeError): # Reject keyword args + hypot(x=1) + with self.assertRaises(TypeError): # Reject values without __float__ + hypot(1.1, 'string', 2.2) + + # Any infinity gives positive infinity. + self.assertEqual(hypot(INF), INF) + self.assertEqual(hypot(0, INF), INF) + self.assertEqual(hypot(10, INF), INF) + self.assertEqual(hypot(-10, INF), INF) + self.assertEqual(hypot(NAN, INF), INF) + self.assertEqual(hypot(INF, NAN), INF) + self.assertEqual(hypot(NINF, NAN), INF) + self.assertEqual(hypot(NAN, NINF), INF) + self.assertEqual(hypot(-INF, INF), INF) + self.assertEqual(hypot(-INF, -INF), INF) + self.assertEqual(hypot(10, -INF), INF) + + # If no infinity, any NaN gives a Nan. + self.assertTrue(math.isnan(hypot(NAN))) + self.assertTrue(math.isnan(hypot(0, NAN))) + self.assertTrue(math.isnan(hypot(NAN, 10))) + self.assertTrue(math.isnan(hypot(10, NAN))) + self.assertTrue(math.isnan(hypot(NAN, NAN))) + self.assertTrue(math.isnan(hypot(NAN))) + + # Verify scaling for extremely large values + fourthmax = FLOAT_MAX / 4.0 + for n in range(32): + self.assertEqual(hypot(*([fourthmax]*n)), fourthmax * math.sqrt(n)) + + # Verify scaling for extremely small values + for exp in range(32): + scale = FLOAT_MIN / 2.0 ** exp + self.assertEqual(math.hypot(4*scale, 3*scale), 5*scale) def testLdexp(self): self.assertRaises(TypeError, math.ldexp) |