mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
bpo-33089: Multidimensional math.hypot() (GH-8474)
This commit is contained in:
parent
5032692746
commit
c6dabe37e3
5 changed files with 144 additions and 82 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue