From 1e6be789fa38009eee479d5b3af291fb86a5a9d1 Mon Sep 17 00:00:00 2001 From: "mark.dickinson" Date: Thu, 11 Dec 2008 19:28:08 +0000 Subject: [PATCH] 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. git-svn-id: http://svn.python.org/projects/python/trunk@67707 6015fed2-1504-0410-9fe1-9d1591cc4771 --- Misc/NEWS | 3 +++ Modules/mathmodule.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 557151d639..be89fb56f2 100644 --- 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. diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 79c55d863b..5087ecc481 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -137,6 +137,58 @@ m_atan2(double y, double 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, -- 2.11.4.GIT