From 866964c3a3823c8d42c51a41c5c7264a569200b4 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 14 Dec 2002 19:51:34 +0000 Subject: Apply SF patch 652930: Add optional base argument to math.log(x[, base]). --- Doc/lib/libmath.tex | 6 +++-- Lib/test/test_math.py | 1 + Misc/NEWS | 2 ++ Modules/mathmodule.c | 62 ++++++++++++++++++++++++++++++++++++++------------- 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/Doc/lib/libmath.tex b/Doc/lib/libmath.tex index f013e23..1dc4365 100644 --- a/Doc/lib/libmath.tex +++ b/Doc/lib/libmath.tex @@ -86,8 +86,10 @@ Return the Euclidean distance, \code{sqrt(\var{x}*\var{x} + \var{y}*\var{y})}. Return \code{\var{x} * (2**\var{i})}. \end{funcdesc} -\begin{funcdesc}{log}{x} -Return the natural logarithm of \var{x}. +\begin{funcdesc}{log}{x\optional{, base}} +Returns the logarithm of \var{x} to the given base. +If the base is not specified, returns the natural logarithm of \var{x}. +\versionchanged[\var{base} argument added]{2.3} \end{funcdesc} \begin{funcdesc}{log10}{x} diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 2d9b55b..8063025 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -113,6 +113,7 @@ print 'log' testit('log(1/e)', math.log(1/math.e), -1) testit('log(1)', math.log(1), 0) testit('log(e)', math.log(math.e), 1) +testit('log(32,2)', math.log(32,2), 5) print 'log10' testit('log10(0.1)', math.log10(0.1), -1) diff --git a/Misc/NEWS b/Misc/NEWS index dc04ea6..7eb828f 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -564,6 +564,8 @@ Library - Added conversion functions math.degrees() and math.radians(). +- math.log() now takes an optional argument: math.log(x[, base]). + - ftplib.retrlines() now tests for callback is None rather than testing for False. Was causing an error when given a callback object which was callable but also returned len() as zero. The change may diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index cbb0000..2572886 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -221,18 +221,8 @@ PyDoc_STRVAR(math_modf_doc, */ static PyObject* -loghelper(PyObject* args, double (*func)(double), char *name) +loghelper(PyObject* args, double (*func)(double), char *format, PyObject *arg) { - PyObject *arg; - char format[16]; - - /* See whether this is a long. */ - format[0] = 'O'; - format[1] = ':'; - strcpy(format + 2, name); - if (! PyArg_ParseTuple(args, format, &arg)) - return NULL; - /* If it is long, do it ourselves. */ if (PyLong_Check(arg)) { double x; @@ -252,23 +242,65 @@ loghelper(PyObject* args, double (*func)(double), char *name) } /* Else let libm handle it by itself. */ - format[0] = 'd'; return math_1(args, func, format); } static PyObject * math_log(PyObject *self, PyObject *args) { - return loghelper(args, log, "log"); + PyObject *arg; + PyObject *base = NULL; + PyObject *num, *den; + PyObject *ans; + PyObject *newargs; + + if (! PyArg_ParseTuple(args, "O|O:log", &arg, &base)) + return NULL; + if (base == NULL) + return loghelper(args, log, "d:log", arg); + + newargs = PyTuple_New(1); + if (newargs == NULL) + return NULL; + Py_INCREF(arg); + PyTuple_SET_ITEM(newargs, 0, arg); + num = loghelper(newargs, log, "d:log", arg); + Py_DECREF(newargs); + if (num == NULL) + return NULL; + + newargs = PyTuple_New(1); + if (newargs == NULL) { + Py_DECREF(num); + return NULL; + } + Py_INCREF(base); + PyTuple_SET_ITEM(newargs, 0, base); + den = loghelper(newargs, log, "d:log", base); + Py_DECREF(newargs); + if (den == NULL) { + Py_DECREF(num); + return NULL; + } + + ans = PyNumber_Divide(num, den); + Py_DECREF(num); + Py_DECREF(den); + return ans; } PyDoc_STRVAR(math_log_doc, -"log(x) -> the natural logarithm (base e) of x."); +"log(x[, base]) -> the logarithm of x to the given base.\n\ +If the base not specified, returns the natural logarithm (base e) of x."); static PyObject * math_log10(PyObject *self, PyObject *args) { - return loghelper(args, log10, "log10"); + PyObject *arg; + + if (! PyArg_ParseTuple(args, "O:log10", &arg)) + return NULL; + return loghelper(args, log10, "d:log10", arg); } PyDoc_STRVAR(math_log10_doc, -- cgit v0.12