Repository navigation
log(Decimal(x)) is broken for large x #106502
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Jul 7, 2023 The
mathmodule is really for floats.decimalhas its own algorithms:>>> import decimal >>> x = decimal.Decimal(300**300) >>> x.ln() Decimal('1711.134742396860317829368444')
Reacted by sunmy2019, Michael M. and Yu-Sheng Li- addedstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
on Jul 7, 2023 Actually
>>> float(decimal.Decimal(300**300)) inf
You should not rely on
math.logwhich is designed forfloat.I understand all of that. What I am asking is following: Does documentation/specification states this restrictions?
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))If the argument is outside the range of a Python float, an OverflowError will be raised.
That's only true for
intandfloat.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__().
- removedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Jul 8, 2023 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>))- thelog()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 themath.frexp()do deal with big integers in this function like in thelog()? (This will break thex == m * 2**einvariant, however.)I think this should be closed. We can open a separate issue for improving the documentation if that's needed.
issue is that for large x
math.log(Decimal(x))returnsinfI am not sure if that is an issue with documentation or implementation