[pypy-commit] pypy default: compute mindigits based on the base, instead of taking a worst-case number

cfbolz noreply at buildbot.pypy.org
Wed Jul 17 23:04:27 CEST 2013


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: 
Changeset: r65451:02e7af864e43
Date: 2013-07-17 21:37 +0200
http://bitbucket.org/pypy/pypy/changeset/02e7af864e43/

Log:	compute mindigits based on the base, instead of taking a worst-case
	number

diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -2060,21 +2060,35 @@
 
 _FORMAT_MINDIGITS = 5 # 36 ** 5 fits in 32 bits, there may be a better choice for this
 
+
 class _PartsCache(object):
     def __init__(self):
         # 36 - 3, because bases 0, 1 make no sense
         # and 2 is handled differently
-        self.parts_cache = [None] * 33
+        self.parts_cache = [None] * 34
+        self.mindigits = [0] * 34
+
+        for i in range(34):
+            base = i + 3
+            mindigits = 1
+            while base ** mindigits < sys.maxint:
+                mindigits += 1
+            mindigits -= 1
+            self.mindigits[i] = mindigits
 
     def get_cached_parts(self, base):
-        res = self.parts_cache[base - 3]
+        index = base - 3
+        res = self.parts_cache[index]
         if res is None:
             rbase = rbigint.fromint(base)
-            part = rbase.pow(rbigint.fromint(_FORMAT_MINDIGITS))
+            part = rbase.pow(rbigint.fromint(self.mindigits[index]))
             res = [part]
             self.parts_cache[base - 3] = res
         return res
 
+    def get_mindigits(self, base):
+        return self.mindigits[base - 3]
+
 _parts_cache = _PartsCache()
 
 def _format_int(val, digits):
@@ -2087,7 +2101,7 @@
     return "".join(out)
 
 
-def _format_recursive(x, i, output, pts, digits, size_prefix):
+def _format_recursive(x, i, output, pts, digits, size_prefix, mindigits):
     # bottomed out with min_digit sized pieces
     # use str of ints
     if i < 0:
@@ -2098,12 +2112,12 @@
                 output.append(s)
         else:
             s = _format_int(x.toint(), digits)
-            output.append_multiple_char(digits[0], _FORMAT_MINDIGITS - len(s))
+            output.append_multiple_char(digits[0], mindigits - len(s))
             output.append(s)
     else:
         top, bot = x.divmod(pts[i]) # split the number
-        _format_recursive(top, i-1, output, pts, digits, size_prefix)
-        _format_recursive(bot, i-1, output, pts, digits, size_prefix)
+        _format_recursive(top, i-1, output, pts, digits, size_prefix, mindigits)
+        _format_recursive(bot, i-1, output, pts, digits, size_prefix, mindigits)
 
 def _format(x, digits, prefix='', suffix=''):
     if x.sign == 0:
@@ -2119,7 +2133,8 @@
     two = rbigint.fromint(2)
 
     pts = _parts_cache.get_cached_parts(base)
-    stringsize = _FORMAT_MINDIGITS
+    mindigits = _parts_cache.get_mindigits(base)
+    stringsize = mindigits
     startindex = 0
     for startindex, part in enumerate(pts):
         if not part.lt(x):
@@ -2140,7 +2155,7 @@
     if negative:
         output.append('-')
     output.append(prefix)
-    _format_recursive(x, startindex, output, pts, digits, output.getlength())
+    _format_recursive(x, startindex, output, pts, digits, output.getlength(), mindigits)
 
     output.append(suffix)
     return output.build()


More information about the pypy-commit mailing list