diff options
-rw-r--r-- | Include/pyport.h | 27 | ||||
-rw-r--r-- | Modules/mathmodule.c | 10 |
2 files changed, 25 insertions, 12 deletions
diff --git a/Include/pyport.h b/Include/pyport.h index 79b92c3..7477f07 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -273,21 +273,34 @@ extern "C" { (X) == -Py_HUGE_VAL)) #endif -/* Py_SET_ERANGE_ON_OVERFLOW(x) +/* Py_SET_ERRNO_ON_MATH_ERROR(x) * If a libm function did not set errno, but it looks like the result - * overflowed, set errno to ERANGE. Set errno to 0 before calling a libm - * function, and invoke this macro after, passing the function result. + * overflowed or not-a-number, set errno to ERANGE or EDOM. Set errno + * to 0 before calling a libm function, and invoke this macro after, + * passing the function result. * Caution: * This isn't reliable. See Py_OVERFLOWED comments. * X is evaluated more than once. */ -#define Py_SET_ERANGE_IF_OVERFLOW(X) \ +#if defined(__FreeBSD__) || defined(__OpenBSD__) +#define _Py_SET_EDOM_FOR_NAN(X) if (isnan(X)) errno = EDOM; +#else +#define _Py_SET_EDOM_FOR_NAN(X) ; +#endif +#define Py_SET_ERRNO_ON_MATH_ERROR(X) \ do { \ - if (errno == 0 && ((X) == Py_HUGE_VAL || \ - (X) == -Py_HUGE_VAL)) \ - errno = ERANGE; \ + if (errno == 0) { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \ + errno = ERANGE; \ + else _Py_SET_EDOM_FOR_NAN(X) \ + } \ } while(0) +/* Py_SET_ERANGE_ON_OVERFLOW(x) + * An alias of Py_SET_ERRNO_ON_MATH_ERROR for backward-compatibility. + */ +#define Py_SET_ERANGE_IF_OVERFLOW(X) Py_SET_ERRNO_ON_MATH_ERROR(X) + /* Py_ADJUST_ERANGE1(x) * Py_ADJUST_ERANGE2(x, y) * Set errno to 0 before calling a libm function, and invoke one of these diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 48c981a..2605114 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -57,7 +57,7 @@ math_1(PyObject *args, double (*func) (double), char *argsfmt) PyFPE_START_PROTECT("in math_1", return 0) x = (*func)(x); PyFPE_END_PROTECT(x) - Py_SET_ERANGE_IF_OVERFLOW(x); + Py_SET_ERRNO_ON_MATH_ERROR(x); if (errno && is_error(x)) return NULL; else @@ -74,7 +74,7 @@ math_2(PyObject *args, double (*func) (double, double), char *argsfmt) PyFPE_START_PROTECT("in math_2", return 0) x = (*func)(x, y); PyFPE_END_PROTECT(x) - Py_SET_ERANGE_IF_OVERFLOW(x); + Py_SET_ERRNO_ON_MATH_ERROR(x); if (errno && is_error(x)) return NULL; else @@ -143,7 +143,7 @@ math_frexp(PyObject *self, PyObject *args) return NULL; errno = 0; x = frexp(x, &i); - Py_SET_ERANGE_IF_OVERFLOW(x); + Py_SET_ERRNO_ON_MATH_ERROR(x); if (errno && is_error(x)) return NULL; else @@ -168,7 +168,7 @@ math_ldexp(PyObject *self, PyObject *args) PyFPE_START_PROTECT("ldexp", return 0) x = ldexp(x, exp); PyFPE_END_PROTECT(x) - Py_SET_ERANGE_IF_OVERFLOW(x); + Py_SET_ERRNO_ON_MATH_ERROR(x); if (errno && is_error(x)) return NULL; else @@ -186,7 +186,7 @@ math_modf(PyObject *self, PyObject *args) return NULL; errno = 0; x = modf(x, &y); - Py_SET_ERANGE_IF_OVERFLOW(x); + Py_SET_ERRNO_ON_MATH_ERROR(x); if (errno && is_error(x)) return NULL; else |