[issue47134] Document the meaning of the number in OverflowError
Eryk Sun
report at bugs.python.org
Sat Mar 26 18:46:01 EDT 2022
Eryk Sun <eryksun at gmail.com> added the comment:
The error code for `1e+300 ** 2` is ERANGE, from calling libm pow(). Since pow() returns a double, there's no way to indicate an error in the return value. Instead, C errno is set to 0 beforehand and checked for a non-zero error value after the call. If the error code isn't ERANGE, then float.__pow__() raises ValueError instead of OverflowError. Here's the relevant snippet from float_pow() in Objects/floatobject.c:
/* Now iv and iw are finite, iw is nonzero, and iv is
* positive and not equal to 1.0. We finally allow
* the platform pow to step in and do the rest.
*/
errno = 0;
ix = pow(iv, iw);
_Py_ADJUST_ERANGE1(ix);
if (negate_result)
ix = -ix;
if (errno != 0) {
/* We don't expect any errno value other than ERANGE, but
* the range of libm bugs appears unbounded.
*/
PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :
PyExc_ValueError);
return NULL;
}
return PyFloat_FromDouble(ix);
Here's a direct example using ctypes:
import ctypes
import errno
libm = ctypes.CDLL('libm.so.6', use_errno=True)
libm.pow.argtypes = (ctypes.c_double, ctypes.c_double)
libm.pow.restype = ctypes.c_double
>>> errno.ERANGE
34
>>> ctypes.set_errno(0)
0
>>> libm.pow(1e300, 2)
inf
>>> ctypes.get_errno() == errno.ERANGE
True
----------
nosy: +eryksun
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue47134>
_______________________________________
More information about the Python-bugs-list
mailing list