]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Apply SF patch 652930: Add optional base argument to math.log(x[, base]).
authorRaymond Hettinger <python@rcn.com>
Sat, 14 Dec 2002 19:51:34 +0000 (19:51 +0000)
committerRaymond Hettinger <python@rcn.com>
Sat, 14 Dec 2002 19:51:34 +0000 (19:51 +0000)
Doc/lib/libmath.tex
Lib/test/test_math.py
Misc/NEWS
Modules/mathmodule.c

index f013e23a114ec5c9974ba3717e64940a1ac6ab2c..1dc43655fa148b4a1920675170bb7684383bbcf0 100644 (file)
@@ -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}
index 2d9b55b2f506a2b1b88f9b56451527b9994b367b..8063025d50d809962147f3640fd8e4e88446045a 100644 (file)
@@ -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)
index dc04ea6450a4ea3e3dca7fcffe67394fffb273fc..7eb828fdc4d49d7235d2d726a384f96b173fdfe9 100644 (file)
--- 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
index cbb00007ec8f2d0955590d9c778fadfd573909d5..25728864fffe5ab0fdb6d4fa2f3178ad94e96006 100644 (file)
@@ -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,