Repository navigation
Incorrect docstring of math.exp (math.e vs Euler's number) #101594
Description
Activity
"Return the exponential of x" implies that it returns x to some power, which is wrong. Even if we read it the other way, "the exponential of x" doesn't tell us what number is being raised to the power of x. Which exponential? There are an infinite number of possible exponentials (something) to the power of x.
The current description is much better than the description in the Mathematica docs, where you have to click on the "Details" section to finally discover that
Exp[z] is converted to E^z.The problem with the current text is that here is a disambiguation of the Euler's number e vs the math.e (an approximation of).
That's not a problem. We know from the relevant domain knowledge that all float constants and operations refer to floats, not real numbers. We don't need to repeat that for every single function. Unlike Mathematica, the
mathmodule does not do symbolic exact maths.In any case, the docstring does not have to repeat the full documentation. It is okay for the docstring to be an abbreviated summary.
"Return the exponential of x" implies that it returns x to some power, which is wrong.
Not. It's exactly
e**x, see also the matlab docs, but indeed: maybe this convention is less popular. Other variants (more verbose): "the natural exponential function" or just "the exponential function", see the mathworld.We know from the relevant domain knowledge that all float constants and operations refer to floats, not real numbers.
Then this will be incorrect, because the
math.exp(x)is not actually themath.e**x. The mentioned full documention does explain why.In any case, the docstring does not have to repeat the full documentation.
That's true. But even you above mistakenly interpreted
ein the docstring as the float numbermath.e, that shows that there is an issue.Here's my 2 cents: since the
mathmodule is based on the C standard and AFAIKmath.expsimply callsexpfrom<math.h>(which itself is technically implementation-dependent), I would simply copy the description from §7.12.6.1/2, ISO/IEC 9899:1999:TC3, namelyCompute the base-e exponential of x.
Now, even with the above sentence or even if you say "the exponential of x", you could argue that it's still not the case since the actual result is an approximation. In particular, you cannot say that it uses Euler's number. Therefore, I don't think we need to be extremely verbose in the docstring if we have an online doc and if the actual result also depends on the libc implementation. A more precise docstring would be
Compute an approximation of the base-e exponential of x. The result is more precise than math.e ** x.
I however think that this is more confusing for normal users.
I however think that this is more confusing for normal users.
As a normal user, I've thought that both ways are the same and
exp()is just a pre-**legacy artifact. So the precision note is crucial.What I thought users could find confusing is the term "approximation" because the way it is approximated is entirely implementation-dependent. But if it's not confusing, then it's good, I think ? I personally come from C/C++, so I've always used
exp()since I was told not to use constants directly.I don't think we need to be extremely verbose in the docstring
In fact, what's I'm suggesting is to be less verbose in docstring and sphinx docs. E.g. the docstring of exp could be:
Return the exponential function at x.The sphinx docs:
Return the exponential function at x. This is usually more accurate than math.e**x.And so on: we could drop remarks like
(base e)orHere e is the base of natural logarithms.Thanks all for the discussion and suggestions, and thank you to @skirpichev for the PR.
I'm going to close here: the maxim "Practicality beats purity" applies, and I don't think there's any practical problem being solved at this point; in particular, I think removing the references to
eon the basis that they're technically ambiguous harms more than it helps.I agree that there's ambiguity over whether
ein any given docstring meansmath.eor whether it refers to Euler's number, but I'm not seeing any practical problem arising from that ambiguity. The sole exception is that it should be emphasized that users should preferexp(x)overmath.e**xfor accuracy reasons, and the docs already make that point.Technically the same applies to
log:log(x)should be preferred overlog(x, math.e), but in practice it makes no difference - assuming IEEE 754 arithmetic,log(math.e)evaluates to1.0under correct rounding, and on most platforms thelibmaccuracy is good enough thatlog(math.e)does in fact give exactly1.0. Solog(x)andlog(x, math.e)give exactly the same result; the latter is just slightly less efficient. So this doesn't seem worth calling out in the docs.@mdickinson, thank you for review.
So log(x) and log(x, math.e) give exactly the same result;
If we can guarantee that, sorry for a bit off-topic, then base=math.e sounds to be a good default value. What if we adapt the inspect module to keep "symbolic" name in the Signature, does this make sense for you?
@skirpichev Yes, that seems reasonable, if it can be achieved. It's philosophically wrong in that it doesn't match what the implementation actually does, and that still bugs me a little, but I think it passes the "practicality beats purity" test.
that seems reasonable, if it can be achieved.
Yes, I've a toy implementation: #89381 (comment)
It's philosophically wrong in that it doesn't match what the implementation actually does
Instead of "calculated as log(x)/log(base)" we could state something like "equal to log(x)/log(base)".
I would rephrase this as: "Return the exponential of x." (like the Mathematica docs). Same for expm1() or with log()/log1p().
The problem with the current text is that here is a disambiguation of the Euler's number e vs the math.e (an approximation of). Sometimes this is explained in the sphinx docs: e.g. for same exp() it says "Return e raised to the power x, where e = 2.718281… is the base of natural logarithms.". But sometimes not: e.g. for log() or log1p().
I think, using "the exponential of" or "the natural logarithm of" in the docstrings and sphinx docs will be better.
Linked PRs