random number including 1 - i.e. [0,1]

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Tue Jun 9 23:24:07 EDT 2009

On Tue, 09 Jun 2009 18:28:23 -0700, John Yeung wrote:

> The docs are now... sort of correct.  For some values of a and b,
> uniform() can never return b.  Notably, I believe uniform(0, 1) is
> equivalent to random(), and will never return 1.  However, uniform(1, 2)
> CAN return 2, if this is any indication:
>>>> a=0.0
>>>> b=1.0
>>>> a+(b-a)*z < b
> True
>>>> a=1.0
>>>> b=2.0
>>>> a+(b-a)*z < b
> False

But you haven't shown what value z has, so there's no way of interpreting 
that example.

I'd say that uniform(1, 2) should NOT return 2, at least for systems 
which round correctly. Given a random z such that:

0 <= z < 1

and two floats a, b such that:

a < b

(b is strictly the larger of the two) then:

0 <= z < 1

Multiply all sides by (b-a):
    0 <= (b-a)*z < (b-a)

Add a to all sides:
    a <= a + (b-a)*z < b

Hence uniform(a, b) should always return a result less than b, and 
greater or equal to a.

However, there is one proviso: floats are not reals. The above holds true 
for real numbers, but floats are subject to weird rounding effects. That 
means that there may be weird edge cases where Bad Things happen and 
things cancel catastrophically or round incorrectly.

A realistic edge case is that a + (b-a) doesn't always give b:

>>> a = -1e90
>>> b = 1.0
>>> a < b
>>> a + (b-a) == b
>>> a + (b-a)

However, even in this case, it merely narrows the range of possible 
results, it doesn't widen it.


More information about the Python-list mailing list