Skip to content

Commit ee617bd

Browse files
committed
_pydecimal: avoid slow exponentiation in floor division
1 parent 52996aa commit ee617bd

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

Lib/_pydecimal.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@
9292

9393
MIN_ETINY = MIN_EMIN - (MAX_PREC-1)
9494

95+
_LOG_10_BASE_2 = float.fromhex('0x1.a934f0979a371p+1') # log2(10)
96+
9597
# Errors
9698

9799
class DecimalException(ArithmeticError):
@@ -1355,9 +1357,11 @@ def _divide(self, other, context):
13551357
else:
13561358
op2.int *= 10**(op2.exp - op1.exp)
13571359
q, r = divmod(op1.int, op2.int)
1358-
if q < 10**context.prec:
1359-
return (_dec_from_triple(sign, str(q), 0),
1360-
_dec_from_triple(self._sign, str(r), ideal_exp))
1360+
if q.bit_length() < 1 + context.prec * _LOG_10_BASE_2:
1361+
# ensure that the previous check was sufficient
1362+
if len(str_q := str(q)) <= context.prec:
1363+
return (_dec_from_triple(sign, str_q, 0),
1364+
_dec_from_triple(self._sign, str(r), ideal_exp))
13611365

13621366
# Here the quotient is too large to be representable
13631367
ans = context._raise_error(DivisionImpossible,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Avoid hanging in floor division of pure Python :class:`decimal.Decimal`
2+
instances when the context precision is very large. Patch by Bénédikt Tran.

0 commit comments

Comments
 (0)