]> granicus.if.org Git - python/commitdiff
Remove support for nth root of negative numbers with odd powers.
authorSteven D'Aprano <steve@pearwood.info>
Wed, 24 Aug 2016 02:48:12 +0000 (12:48 +1000)
committerSteven D'Aprano <steve@pearwood.info>
Wed, 24 Aug 2016 02:48:12 +0000 (12:48 +1000)
Although nth roots of negative numbers are real for odd n, the
statistics module doesn't make use of this. Remove support for
negative roots from the private _nth_root function, which
simplifies the test suite.

Lib/statistics.py
Lib/test/test_statistics.py

index 632127af4da75a9bd4845e4e7b73f840d6f63e68..40c72db0c064e0581246368af2a3a542b35e4f6a 100644 (file)
@@ -335,10 +335,7 @@ class _nroot_NS:
         """Handle nth root of Reals, treated as a float."""
         assert isinstance(n, int) and n > 1
         if x < 0:
-            if n%2 == 0:
-                raise ValueError('domain error: even root of negative number')
-            else:
-                return -_nroot_NS.nroot(-x, n)
+            raise ValueError('domain error: root of negative number')
         elif x == 0:
             return math.copysign(0.0, x)
         elif x > 0:
@@ -433,6 +430,8 @@ class _nroot_NS:
             else:
                 # Preserve the input NAN.
                 return x
+        if x < 0:
+            raise ValueError('domain error: root of negative number')
         if x.is_infinite():
             return x
         # FIXME this hasn't had the extensive testing of the float
index dff0cd4476b4a7114e7a1284cf2410534cf24dc8..9443ff0c61fc800b3733c71440daf0f319bb3356 100644 (file)
@@ -1095,13 +1095,6 @@ class Test_Nth_Root(NumericTestCase):
                 with self.subTest(n=n, inf=INF):
                     self.assertEqual(self.nroot(INF, n), INF)
 
-    def testNInf(self):
-        # Test that the root of -inf is -inf for odd n.
-        for NINF in (float('-inf'), decimal.Decimal('-inf')):
-            for n in range(3, 11, 2):
-                with self.subTest(n=n, inf=NINF):
-                    self.assertEqual(self.nroot(NINF, n), NINF)
-
     # FIXME: need to check Decimal zeroes too.
     def test_zero(self):
         # Test that the root of +0.0 is +0.0.
@@ -1157,13 +1150,15 @@ class Test_Nth_Root(NumericTestCase):
             with self.subTest(x=x):
                 self.assertRaises(TypeError, self.nroot, x, 3)
 
-    def testNegativeEvenPower(self):
-        # Test negative x with even n raises correctly.
+    def testNegativeError(self):
+        # Test negative x raises correctly.
         x = random.uniform(-20.0, -0.1)
         assert x < 0
-        for n in range(2, 9, 2):
+        for n in range(3, 7):
             with self.subTest(x=x, n=n):
                 self.assertRaises(ValueError, self.nroot, x, n)
+        # And Decimal.
+        self.assertRaises(ValueError, self.nroot, Decimal(-27), 3)
 
     # --- Test that nroot is never worse than calling math.pow() ---
 
@@ -1216,25 +1211,11 @@ class Test_Nth_Root(NumericTestCase):
                     x = i**n
                     self.assertEqual(self.nroot(x, n), i)
 
-    def testExactPowersNegatives(self):
-        # Test that small negative integer powers are calculated exactly.
-        for i in range(-1, -51, -1):
-            for n in range(3, 16, 2):
-                if (i, n) == (-35, 13):
-                    # See testExpectedFailure35p13
-                    continue
-                with self.subTest(i=i, n=n):
-                    x = i**n
-                    assert sign(x) == -1
-                    self.assertEqual(self.nroot(x, n), i)
-
     def testExpectedFailure35p13(self):
         # Test the expected failure 35**13 is almost exact.
         x = 35**13
         err = abs(self.nroot(x, 13) - 35)
         self.assertLessEqual(err, 0.000000001)
-        err = abs(self.nroot(-x, 13) + 35)
-        self.assertLessEqual(err, 0.000000001)
 
     def testOne(self):
         # Test that the root of 1.0 is 1.0.