You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
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__().
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.)
Activity
tim-one commentedon Jul 7, 2023
The
mathmodule is really for floats.decimalhas its own algorithms:sunmy2019 commentedon Jul 7, 2023
Actually
sunmy2019 commentedon Jul 7, 2023
You should not rely on
math.logwhich is designed forfloat.ra1u commentedon Jul 7, 2023
I understand all of that. What I am asking is following: Does documentation/specification states this restrictions?
ra1u commentedon Jul 7, 2023
@sunmy2019
There is another issue with float() implementation .
From: https://docs.python.org/3/library/functions.html?#float
According to this OverflowError should be raised from
float(decimal.Decimal(300**300))sunmy2019 commentedon Jul 7, 2023
That's only true for
intandfloat.You should look at the following paragraph for general Python objects.
skirpichev commentedon Oct 4, 2023
On one hand, it might be considered as a tiny documentation issue for the
float()type.Here is a patch.
On another hand, there could be some confusion in this case:
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.)mdickinson commentedon Jun 24, 2024
I think this should be closed. We can open a separate issue for improving the documentation if that's needed.