]> granicus.if.org Git - python/commitdiff
Merged revisions 67707 via svnmerge from
authorMark Dickinson <dickinsm@gmail.com>
Thu, 11 Dec 2008 21:59:08 +0000 (21:59 +0000)
committerMark Dickinson <dickinsm@gmail.com>
Thu, 11 Dec 2008 21:59:08 +0000 (21:59 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r67707 | mark.dickinson | 2008-12-11 19:28:08 +0000 (Thu, 11 Dec 2008) | 5 lines

  Issues #3167, #3682: tests for math.log and math.log10 were failing on
  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 898e9a2e354dd8f251dd7803ae4a6fb37e95293a..93b69143cb823448f4e8c192681b9a606c5a47d5 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -155,6 +155,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,