]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issues #3167, #3682: tests for math.log and math.log10 were failing on
authorMark Dickinson <dickinsm@gmail.com>
Thu, 11 Dec 2008 19:28:08 +0000 (19:28 +0000)
committerMark Dickinson <dickinsm@gmail.com>
Thu, 11 Dec 2008 19:28:08 +0000 (19:28 +0000)
Solaris and OpenBSD.  Fix this by handling special values and domain
errors directly in mathmodule.c, passing only positive nonspecial floats
to the system log/log10.

Misc/NEWS
Modules/mathmodule.c

index 557151d6390148ee371329904fccca9f4fc8c174..be89fb56f25c5c20ebc3d1940defb012d9593ccd 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -160,6 +160,9 @@ C-API
 Extension Modules
 -----------------
 
+- Issues #3167, #3682: Fix test_math failures for log, log10 on Solaris,
+  OpenBSD.
+
 - Issue #4365: Add crtassem.h constants to the msvcrt module.
 
 - Issue #4396: The parser module now correctly validates the with statement.
index 79c55d863ba849260d4f6297de090bf80c43f4db..5087ecc481bbef4030c3774c31ce483310029feb 100644 (file)
@@ -136,6 +136,58 @@ m_atan2(double y, double x)
        return atan2(y, x);
 }
 
+/*
+    Various platforms (Solaris, OpenBSD) do nonstandard things for log(0),
+    log(-ve), log(NaN).  Here are wrappers for log and log10 that deal with
+    special values directly, passing positive non-special values through to
+    the system log/log10.
+ */
+
+static double
+m_log(double x)
+{
+       if (Py_IS_FINITE(x)) {
+               if (x > 0.0)
+                       return log(x);
+               errno = EDOM;
+               if (x == 0.0)
+                       return -Py_HUGE_VAL; /* log(0) = -inf */
+               else
+                       return Py_NAN; /* log(-ve) = nan */
+       }
+       else if (Py_IS_NAN(x))
+               return x; /* log(nan) = nan */
+       else if (x > 0.0)
+               return x; /* log(inf) = inf */
+       else {
+               errno = EDOM;
+               return Py_NAN; /* log(-inf) = nan */
+       }
+}
+
+static double
+m_log10(double x)
+{
+       if (Py_IS_FINITE(x)) {
+               if (x > 0.0)
+                       return log10(x);
+               errno = EDOM;
+               if (x == 0.0)
+                       return -Py_HUGE_VAL; /* log10(0) = -inf */
+               else
+                       return Py_NAN; /* log10(-ve) = nan */
+       }
+       else if (Py_IS_NAN(x))
+               return x; /* log10(nan) = nan */
+       else if (x > 0.0)
+               return x; /* log10(inf) = inf */
+       else {
+               errno = EDOM;
+               return Py_NAN; /* log10(-inf) = nan */
+       }
+}
+
+
 /*
    math_1 is used to wrap a libm function f that takes a double
    arguments and returns a double.
@@ -758,11 +810,11 @@ math_log(PyObject *self, PyObject *args)
        if (!PyArg_UnpackTuple(args, "log", 1, 2, &arg, &base))
                return NULL;
 
-       num = loghelper(arg, log, "log");
+       num = loghelper(arg, m_log, "log");
        if (num == NULL || base == NULL)
                return num;
 
-       den = loghelper(base, log, "log");
+       den = loghelper(base, m_log, "log");
        if (den == NULL) {
                Py_DECREF(num);
                return NULL;
@@ -781,7 +833,7 @@ If the base not specified, returns the natural logarithm (base e) of x.");
 static PyObject *
 math_log10(PyObject *self, PyObject *arg)
 {
-       return loghelper(arg, log10, "log10");
+       return loghelper(arg, m_log10, "log10");
 }
 
 PyDoc_STRVAR(math_log10_doc,