Commit 866964c3 authored by Raymond Hettinger's avatar Raymond Hettinger

Apply SF patch 652930: Add optional base argument to math.log(x[, base]).

parent a828586c
......@@ -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}
......
......@@ -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)
......
......@@ -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
......
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment