]> granicus.if.org Git - python/commitdiff
Patch #871657: Set EDOM for `nan' return values on FreeBSD and OpenBSD.
authorHye-Shik Chang <hyeshik@gmail.com>
Mon, 22 Mar 2004 08:43:55 +0000 (08:43 +0000)
committerHye-Shik Chang <hyeshik@gmail.com>
Mon, 22 Mar 2004 08:43:55 +0000 (08:43 +0000)
This fixes a problem that math.sqrt(-1) doesn't raise math.error.

Include/pyport.h
Modules/mathmodule.c

index 79b92c3de177c678daa3e22adb691f8027186761..7477f07d260104bcffa10027dc84b946a78ee685 100644 (file)
@@ -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
index 48c981a5ab09079cf850f89883a999e02f43c3a5..260511400ecf38b6f74d8e34a25a40cec1777213 100644 (file)
@@ -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