[Python-checkins] r82649 - in python/branches/py3k: Lib/decimal.py Lib/test/decimaltestdata/extra.decTest Misc/NEWS

mark.dickinson python-checkins at python.org
Thu Jul 8 21:03:34 CEST 2010


Author: mark.dickinson
Date: Thu Jul  8 21:03:34 2010
New Revision: 82649

Log:
Fix a performance issue in Decimal.pow.  Thanks Stefan Krah for finding this.

Modified:
   python/branches/py3k/Lib/decimal.py
   python/branches/py3k/Lib/test/decimaltestdata/extra.decTest
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/decimal.py
==============================================================================
--- python/branches/py3k/Lib/decimal.py	(original)
+++ python/branches/py3k/Lib/decimal.py	Thu Jul  8 21:03:34 2010
@@ -2047,12 +2047,14 @@
         # case where xc == 1: result is 10**(xe*y), with xe*y
         # required to be an integer
         if xc == 1:
-            if ye >= 0:
-                exponent = xe*yc*10**ye
-            else:
-                exponent, remainder = divmod(xe*yc, 10**-ye)
-                if remainder:
-                    return None
+            xe *= yc
+            # result is now 10**(xe * 10**ye);  xe * 10**ye must be integral
+            while xe % 10 == 0:
+                xe //= 10
+                ye += 1
+            if ye < 0:
+                return None
+            exponent = xe * 10**ye
             if y.sign == 1:
                 exponent = -exponent
             # if other is a nonnegative integer, use ideal exponent

Modified: python/branches/py3k/Lib/test/decimaltestdata/extra.decTest
==============================================================================
--- python/branches/py3k/Lib/test/decimaltestdata/extra.decTest	(original)
+++ python/branches/py3k/Lib/test/decimaltestdata/extra.decTest	Thu Jul  8 21:03:34 2010
@@ -213,7 +213,20 @@
 extr1659 shift 1234567 4 -> 0
 extr1660 shift 1234567 5 -> NaN Invalid_operation
 
+-- Cases where the power function was impossibly slow to determine that the
+-- result is inexact.  Thanks Stefan Krah for identifying this problem.
+precision: 16
+maxExponent: 999999999
+minExponent: -999999999
+extr1700 power 10 1e-999999999 -> 1.000000000000000 Inexact Rounded
+extr1701 power 100.0 -557.71e-742888888 -> 1.000000000000000 Inexact Rounded
+extr1702 power 10 1e-100 -> 1.000000000000000 Inexact Rounded
 
+-- A couple of interesting exact cases for power.  Note that the specification
+-- requires these to be reported as Inexact.
+extr1710 power 1e375 56e-3 -> 1.000000000000000E+21 Inexact Rounded
+extr1711 power 10000 0.75 -> 1000.000000000000 Inexact Rounded
+extr1712 power 1e-24 0.875 -> 1.000000000000000E-21 Inexact Rounded
 
 -- Tests for the is_* boolean operations
 precision: 9

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jul  8 21:03:34 2010
@@ -470,6 +470,10 @@
 Library
 -------
 
+- Fix extreme speed issue in Decimal.pow when the base is an exact
+  power of 10 and the exponent is tiny (for example,
+  Decimal(10) ** Decimal('1e-999999999')).
+
 - Issue #9186: Fix math.log1p(-1.0) to raise ValueError, not OverflowError.
 
 - Issue #9130: Fix validation of relative imports in parser module.


More information about the Python-checkins mailing list