gh-118610: Centralize power caching in _pylong.py (#118611)

A new `compute_powers()` function computes all and only the powers of the base the various base-conversion functions need, as efficiently as reasonably possible (turns out that invoking `**`is needed at most once). This typically gives a few % speedup, but the primary point is to simplify the base-conversion functions, which no longer need their own, ad hoc, and less efficient power-caching schemes.

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
Tim Peters 2024-05-07 19:09:09 -05:00 committed by GitHub
parent 2a85bed89d
commit 2f0a338be6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 113 additions and 67 deletions

View file

@ -906,6 +906,18 @@ class PyLongModuleTests(unittest.TestCase):
with self.assertRaises(RuntimeError):
int(big_value)
def test_pylong_roundtrip(self):
from random import randrange, getrandbits
bits = 5000
while bits <= 1_000_000:
bits += randrange(-100, 101) # break bitlength patterns
hibit = 1 << (bits - 1)
n = hibit | getrandbits(bits - 1)
assert n.bit_length() == bits
sn = str(n)
self.assertFalse(sn.startswith('0'))
self.assertEqual(n, int(sn))
bits <<= 1
if __name__ == "__main__":
unittest.main()