FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

log(Decimal(x)) is broken for large x · Issue #106502 · python/cpython · GitHub

Repository navigation

log(Decimal(x)) is broken for large x #106502

Description

issue is that for large x math.log(Decimal(x)) returns inf

I am not sure if that is an issue with documentation or implementation

Python 3.11.4 (main, Jun  7 2023, 10:13:09) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import log
>>> from decimal import Decimal
>>> d = Decimal(300**300)
>>> d
Decimal('136891479058588375991326027382088315966463695625337436471480190078368997177499076593800206155688941388250484440597994042813512732765695774566001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
>>> log(d)
inf
>>> log(int(d))
1711.1347423968602

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    on Jul 7, 2023
  2. tim-one commented on Jul 7, 2023

    Member

    The math module is really for floats. decimal has its own algorithms:

    >>> import decimal
    >>> x = decimal.Decimal(300**300)
    >>> x.ln()
    Decimal('1711.134742396860317829368444')
  3. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Jul 7, 2023
  4. sunmy2019 commented on Jul 7, 2023

    Member

    Actually

    >>> float(decimal.Decimal(300**300))
    inf
  5. sunmy2019 commented on Jul 7, 2023

    Member

    You should not rely on math.log which is designed for float.

  6. ra1u commented on Jul 7, 2023

    Author

    I understand all of that. What I am asking is following: Does documentation/specification states this restrictions?

  7. ra1u commented on Jul 7, 2023

    Author

    @sunmy2019

    There is another issue with float() implementation .

    From: https://docs.python.org/3/library/functions.html?#float

    If the argument is outside the range of a Python float, an OverflowError will be raised.

    According to this OverflowError should be raised from float(decimal.Decimal(300**300))

  8. sunmy2019 commented on Jul 7, 2023

    Member

    If the argument is outside the range of a Python float, an OverflowError will be raised.

    That's only true for int and float.

    Otherwise, if the argument is an integer or a floating point number, a floating point number with the same value (within Python’s floating point precision) is returned. If the argument is outside the range of a Python float, an OverflowError will be raised.

    You should look at the following paragraph for general Python objects.

    For a general Python object x, float(x) delegates to x.__float__(). If __float__() is not defined then it falls back to __index__().

  9. removed
    type-bugAn unexpected behavior, bug, or error
    on Jul 8, 2023
  10. skirpichev commented on Oct 4, 2023

    Member

    On one hand, it might be considered as a tiny documentation issue for the float() type.

    Here is a patch.
    diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
    index 3520609706..2672d243c7 100644
    --- a/Doc/library/functions.rst
    +++ b/Doc/library/functions.rst
    @@ -677,7 +677,7 @@ are always available.  They are listed here in alphabetical order.
     
        Otherwise, if the argument is an integer or a floating point number, a
        floating point number with the same value (within Python's floating point
    -   precision) is returned.  If the argument is outside the range of a Python
    +   precision) is returned.  If an integer is outside the range of a Python
        float, an :exc:`OverflowError` will be raised.
     
        For a general Python object ``x``, ``float(x)`` delegates to
    

    On another hand, there could be some confusion in this case:

    >>> log(int(d))
    1711.1347423968602
    >>> float(int(d))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    OverflowError: int too large to convert to float

    While for other functions of the module, like sin(), we could expect simple type-cast for integer arguments, i.e. sin(<big-int>)=sin(float(<big-int>)) - the log() function is a special one. It uses internally the _PyLong_Frexp() private helper to compute the log even in some cases when an integer argument is outside the range of a Python float.

    @tim-one, shouldn't we document this somehow? Maybe we could expose the _PyLong_Frexp() in the math.frexp() do deal with big integers in this function like in the log()? (This will break the x == m * 2**e invariant, however.)

  11. mdickinson commented on Jun 24, 2024

    Member

    I think this should be closed. We can open a separate issue for improving the documentation if that's needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directory

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL