summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorRaymond Hettinger <rhettinger@users.noreply.github.com>2018-07-28 14:48:04 (GMT)
committerGitHub <noreply@github.com>2018-07-28 14:48:04 (GMT)
commitc6dabe37e3c4d449562182b044184d1756bea037 (patch)
treebbb89623d68962192e810c5327ae98ff28084025 /Lib
parent50326927465c3f5c6c0168fc43310c8e97db0a47 (diff)
downloadcpython-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.py76
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)