summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2002-12-14 19:51:34 (GMT)
committerRaymond Hettinger <python@rcn.com>2002-12-14 19:51:34 (GMT)
commit866964c3a3823c8d42c51a41c5c7264a569200b4 (patch)
tree0ad3fb175d1d8fadb3005ed94ff43a97e82caa0e
parenta828586c3a2a2c07558f8872ef115adc3e24ad9f (diff)
downloadcpython-866964c3a3823c8d42c51a41c5c7264a569200b4.zip
cpython-866964c3a3823c8d42c51a41c5c7264a569200b4.tar.gz
cpython-866964c3a3823c8d42c51a41c5c7264a569200b4.tar.bz2
Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
-rw-r--r--Doc/lib/libmath.tex6
-rw-r--r--Lib/test/test_math.py1
-rw-r--r--Misc/NEWS2
-rw-r--r--Modules/mathmodule.c62
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,