Skip to content

Commit 6f270bd

Browse files
Break a loop between _pydecimal and _pylong.
1 parent 4e978aa commit 6f270bd

File tree

3 files changed

+42
-11
lines changed

3 files changed

+42
-11
lines changed

Lib/_pylong.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
import decimal
1717

1818

19+
_is_pydecimal = hasattr(decimal.Decimal, '_power_exact')
20+
21+
1922
def int_to_decimal(n):
2023
"""Asymptotically fast conversion of an 'int' to Decimal."""
2124

@@ -83,7 +86,7 @@ def inner(n, w):
8386
def int_to_decimal_string(n):
8487
"""Asymptotically fast conversion of an 'int' to a decimal string."""
8588
w = n.bit_length()
86-
if w > 900_000:
89+
if w > 900_000 and not _is_pydecimal:
8790
return str(int_to_decimal(n))
8891

8992
def inner(n, w):
@@ -103,6 +106,7 @@ def inner(n, w):
103106
else:
104107
return inner(n, w)
105108

109+
106110
def _str_to_int_inner(s):
107111
"""Asymptotically fast conversion of a 'str' to an 'int'."""
108112

Lib/test/test_int.py

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -829,17 +829,40 @@ def tearDown(self):
829829
sys.set_int_max_str_digits(self._previous_limit)
830830
super().tearDown()
831831

832-
def test_pylong_int_to_decimal(self):
833-
n = (1 << 100_000) - 1
834-
suffix = '9883109375'
832+
def _test_pylong_int_to_decimal(self, n, suffix):
835833
s = str(n)
836-
assert s[-10:] == suffix
837-
s = str(-n)
838-
assert s[-10:] == suffix
839-
s = '%d' % n
840-
assert s[-10:] == suffix
841-
s = b'%d' % n
842-
assert s[-10:] == suffix.encode('ascii')
834+
self.assertEqual(s[-10:], suffix)
835+
s2 = str(-n)
836+
self.assertEqual(s2, '-' + s)
837+
s3 = '%d' % n
838+
self.assertEqual(s3, s)
839+
s4 = b'%d' % n
840+
self.assertEqual(s4, s.encode('ascii'))
841+
842+
def test_pylong_int_to_decimal(self):
843+
def check(n, suffix):
844+
s = str(n)
845+
self.assertEqual(s[-10:], suffix)
846+
s2 = str(-n)
847+
self.assertEqual(s2, '-' + s)
848+
s3 = '%d' % n
849+
self.assertEqual(s3, s)
850+
s4 = b'%d' % n
851+
self.assertEqual(s4, s.encode('ascii'))
852+
853+
self._test_pylong_int_to_decimal((1 << 100_000), '9883109376')
854+
self._test_pylong_int_to_decimal((1 << 100_000) - 1, '9883109375')
855+
self._test_pylong_int_to_decimal(10**30_000, '0000000000')
856+
self._test_pylong_int_to_decimal(10**30_000 - 1, '9999999999')
857+
self._test_pylong_int_to_decimal(3**60_000, '9313200001')
858+
859+
@support.requires_resource('cpu')
860+
def test_pylong_int_to_decimal_2(self):
861+
self._test_pylong_int_to_decimal(2**1_000_000, '2747109376')
862+
self._test_pylong_int_to_decimal(2**1_000_000 - 1, '2747109375')
863+
self._test_pylong_int_to_decimal(10**300_000, '0000000000')
864+
self._test_pylong_int_to_decimal(10**300_000 - 1, '9999999999')
865+
self._test_pylong_int_to_decimal(3**600_000, '3132000001')
843866

844867
def test_pylong_int_divmod(self):
845868
n = (1 << 100_000)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Break a loop between the Python implementation of the :mod:`decimal` module
2+
and the Python code for integer to string conversion. Optimize integer to
3+
string conversion for values in the range from 10_000 to 270_000 decimal
4+
digits.

0 commit comments

Comments
 (0)