Skip to content

_pydecimal.Decimal.__pow__ tries to compute 10**1000000000000000000 and thus doesn't terminate #118027

Closed
@cfbolz

Description

@cfbolz

Bug report

Bug description:

decimal.Decimal(2) ** 117 does not terminate when using the pure Python implementation _pydecimal.py of the decimal module, and setting the precision to MAX_PREC:

import sys
if len(sys.argv) > 1 and sys.argv[1] == "pydecimal":
    # block _decimal
    sys.modules['_decimal'] = None

import decimal

with decimal.localcontext() as ctx:
    ctx.prec = decimal.MAX_PREC
    ctx.Emax = decimal.MAX_EMAX
    ctx.Emin = decimal.MIN_EMIN
    ctx.traps[decimal.Inexact] = 1
    D2 = decimal.Decimal(2)
    res = D2 ** 117
    print(res)

this behaves as follows:

./python decbug.py # instant
166153499473114484112975882535043072
$ ./python decbug.py pydecimal # hangs
^CTraceback (most recent call last):
  File "/home/cfbolz/projects/cpython/decbug.py", line 14, in <module>
    res = D2 ** 117
          ~~~^^~~~~
  File "/home/cfbolz/projects/cpython/Lib/_pydecimal.py", line 2436, in __pow__
    ans = self._power_exact(other, context.prec + 1)
          ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/cfbolz/projects/cpython/Lib/_pydecimal.py", line 2284, in _power_exact
    if xc > 10**p:
            ~~^^~
KeyboardInterrupt

The bug happens because p is the precision + 1 in the last traceback entry. MAX_PREC = 999999999999999999 on 64-bit systems. Therefore the the code in _power_exact tries to compute 10**1000000000000000000, which obviously won't work.

CPython versions tested on:

3.9, 3.10, 3.11, 3.12, 3.13, CPython main branch

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions