@@ -2217,41 +2217,63 @@ math_modf_impl(PyObject *module, double x)
22172217 in that int is larger than PY_SSIZE_T_MAX. */
22182218
22192219static PyObject *
2220- loghelper (PyObject * arg , double (* func )(double ))
2220+ loghelper_int (PyObject * arg , double (* func )(double ))
22212221{
22222222 /* If it is int, do it ourselves. */
2223- if (PyLong_Check (arg )) {
2224- double x , result ;
2225- Py_ssize_t e ;
2223+ double x , result ;
2224+ Py_ssize_t e ;
22262225
2227- /* Negative or zero inputs give a ValueError. */
2228- if (!_PyLong_IsPositive ((PyLongObject * )arg )) {
2229- PyErr_SetString (PyExc_ValueError ,
2230- "math domain error" );
2231- return NULL ;
2232- }
2226+ /* Negative or zero inputs give a ValueError. */
2227+ if (!_PyLong_IsPositive ((PyLongObject * )arg )) {
2228+ PyErr_SetString (PyExc_ValueError ,
2229+ "math domain error" );
2230+ return NULL ;
2231+ }
22332232
2234- x = PyLong_AsDouble (arg );
2235- if (x == -1.0 && PyErr_Occurred ()) {
2236- if (!PyErr_ExceptionMatches (PyExc_OverflowError ))
2237- return NULL ;
2238- /* Here the conversion to double overflowed, but it's possible
2239- to compute the log anyway. Clear the exception and continue. */
2240- PyErr_Clear ();
2241- x = _PyLong_Frexp ((PyLongObject * )arg , & e );
2242- if (x == -1.0 && PyErr_Occurred ())
2243- return NULL ;
2244- /* Value is ~= x * 2**e, so the log ~= log(x) + log(2) * e. */
2245- result = func (x ) + func (2.0 ) * e ;
2246- }
2247- else
2248- /* Successfully converted x to a double. */
2249- result = func (x );
2250- return PyFloat_FromDouble (result );
2233+ x = PyLong_AsDouble (arg );
2234+ if (x == -1.0 && PyErr_Occurred ()) {
2235+ if (!PyErr_ExceptionMatches (PyExc_OverflowError ))
2236+ return NULL ;
2237+ /* Here the conversion to double overflowed, but it's possible
2238+ to compute the log anyway. Clear the exception and continue. */
2239+ PyErr_Clear ();
2240+ x = _PyLong_Frexp ((PyLongObject * )arg , & e );
2241+ if (x == -1.0 && PyErr_Occurred ())
2242+ return NULL ;
2243+ /* Value is ~= x * 2**e, so the log ~= log(x) + log(2) * e. */
2244+ result = func (x ) + func (2.0 ) * e ;
22512245 }
2246+ else
2247+ /* Successfully converted x to a double. */
2248+ result = func (x );
2249+ return PyFloat_FromDouble (result );
2250+ }
22522251
2252+ static PyObject *
2253+ loghelper (PyObject * arg , double (* func )(double ))
2254+ {
2255+ /* If it is int, do it ourselves. */
2256+ if (PyLong_Check (arg )) {
2257+ return loghelper_int (arg , func );
2258+ }
22532259 /* Else let libm handle it by itself. */
2254- return math_1 (arg , func , 0 );
2260+ PyObject * res = math_1 (arg , func , 0 );
2261+ if (res == NULL &&
2262+ PyErr_ExceptionMatches (PyExc_OverflowError ) &&
2263+ PyIndex_Check (arg ))
2264+ {
2265+ /* Here the conversion to double overflowed, but it's possible
2266+ to compute the log anyway. Clear the exception, convert to
2267+ integer and continue. */
2268+ PyErr_Clear ();
2269+ arg = _PyNumber_Index (arg );
2270+ if (arg == NULL ) {
2271+ return NULL ;
2272+ }
2273+ res = loghelper_int (arg , func );
2274+ Py_DECREF (arg );
2275+ }
2276+ return res ;
22552277}
22562278
22572279
0 commit comments