Issue 4979: random.uniform can return its upper limit (original) (raw)
The documentation for random.uniform says that random.uniform(a,b) should return a number strictly less than b, assuming a<b. (The result should be strictly less than a if a>b.) Thus both of the following expressions should always evaluate to False:
a<b and b in [random.uniform(a,b) for i in range(20)] a<b and b in [random.uniform(b,a) for i in range(20)]
Yet both of them evaluate to True (except, presumably, one time in a million) after doing the following assignments:
a = 1.0 b = 1.0 + 2.0**-52
Other values of a and b also exist for which random.uniform will sometimes return its upper limit. (For example, the -52 can be increased to -51, -50, etc., with correspondingly less frequent violations of the spec.)
Because this is a case where the code is violating an explicit
specification in the documentation, I'm reporting it as a behavior bug.
But perhaps the behavior is as intended and the documentation is at
fault. For that reason, I'm also emailing docs@python.org.
The documentation would in any case need a little touching up, in that it has a self-contradictory specification for the case where a=b. There is no value N for which a<=N<b, given a=b. That minor touch-up could be combined with allowing the behavior described in this bug report, if that behavior is in fact desired.
The distinction between < and <= is fairly meaningless when applied to a computed floating-point result. I think the docs should be fixed to replace the < with <=. In any case, the b <= N < a bit has the inequalities the wrong way around: presumably it was intended to read b < N <= a. The docs for random.triangular should also be fixed in the same way.
(N.B. What is always true is that the result of random.random() is never 1.0. And that's a useful property---without it, random.uniform(a, b) can even return values outside the closed interval [a, b].)
To me, it doesn't seem worth slowing down random.uniform itself with extra checks: it's the sort of function that often gets called millions of times within a simulation, or numerical algorithm (e.g. Monte-Carlo integration), and it's trivial for the user to add his or her own check if necessary.
I also think it's a nice property that random.uniform currently degrades gracefully when a == b, producing the expected point distribution at a. I wouldn't want to change that.
So: +1 for amending the docs. -1 for changing random.uniform.