Repository navigation
bpo-33089: Multidimensional math.hypot() #8474
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
ec15283
abce2b0
241932e
51c52fc
de3c16b
18babd4
6c412d2
780024b
d82df99
1a32ac7
82a12e5
2d2e3aa
6edd323
9c25c65
c4dfbe5
0734edd
43471a9
3818324
8298444
d785025
ee1374c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -732,29 +732,36 @@ def testHypot(self): | |
| self.assertTrue(math.isnan(math.hypot(NAN, -2.0))) | ||
|
|
||
| def test_multi_hypot(self): | ||
| from decimal import Decimal as D | ||
| from decimal import Decimal | ||
| from fractions import Fraction | ||
|
|
||
| hypot = math.mh | ||
|
|
||
| self.assertEqual(hypot(12.0, 5.0), 13.0) # Float inputs. Exact output. | ||
| self.assertEqual(hypot(12, 5), 13) # Int inputs | ||
| self.assertEqual(hypot(D(12), D(5)), 13) # Decimal inputs | ||
|
|
||
| self.assertEqual(hypot(0.0, 0.0), 0.0) # Max input is zero | ||
| self.assertEqual(hypot(-10.5), 10.5) # Negative input | ||
|
|
||
| with self.assertRaises(TypeError): | ||
| hypot(x=1) # Reject keyword args | ||
|
|
||
| # Test 0 to 4 dimensional inputs | ||
| args = math.e, math.pi, math.sqrt(2.0), math.gamma(3.5) | ||
| # Test different numbers of arguments from zero to five | ||
| 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 special values. | ||
| # 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 | ||
|
|
||
| # 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) | ||
|
|
@@ -764,6 +771,7 @@ def test_multi_hypot(self): | |
| 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))) | ||
|
|
@@ -775,12 +783,12 @@ def test_multi_hypot(self): | |
| halfmax = sys.float_info.max / 2.0 | ||
| for n in range(10): | ||
| self.assertEqual(hypot(*([halfmax]*n)), halfmax * math.sqrt(n)) | ||
|
|
||
| # Verify scaling for extremely small values | ||
| small = sys.float_info.min | ||
| a, b, c = 5, 12, 13 | ||
| for exp in range(32): | ||
| scale = small / 2 ** exp | ||
| self.assertEqual(math.hypot(a*scale, b*scale), c*scale) | ||
| self.assertEqual(math.hypot(12*scale, 5*scale), 13*scale) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes me nervous, because it depends on that happens to be exactly 13.0 despite that 5/12 isn't exactly representable. Would be happier with: because every intermediate value in is exactly representable in binary.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, changed to a 3-4-5 triangle. |
||
|
|
||
| def testLdexp(self): | ||
| self.assertRaises(TypeError, math.ldexp) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add
self.assertEqual(hypot(), 0.0)?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, added an explict test for this case. FWIW, this was already tested in the section "Test different numbers of arguments (from zero to five)".