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

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Thu Jun 11 04:06:16 CEST 2009

```On Wed, 10 Jun 2009 15:32:05 -0500, Robert Kern wrote:

> That's a fair point. However, one issue that hasn't been brought up is
> that it might be confusing to a user why random.random() returns values
> in a half-open interval while random.uniform() claims a closed interval.
> Even for reasonably sophisticated floating point users, it's not
> necessarily obvious that that is the reasoning behind the different
> claims.

Agreed -- the reasoning that a half-open interval [0, 1) for z (random())
leads to a closed interval [a, b] for a+(b-a)*z (uniform()) is *not*
obvious even for people who are aware that floats do funny things. I know
I got caught out by it.

However, rather than a documentation patch, I'd prefer to see uniform()
fixed to return a value in the half-open interval. Something like:

def uniform(self, a, b):
"""Get a random number in the range [a, b)."""
r = a + (b-a) * self.random()
while r == b:  # Guard against (rare) rounding to b.
r = a + (b-a) * self.random()
return r

should do the trick. I think.

Earlier, Mark Dickinson wrote:

"Can you think of a single practical situation where it would matter
that, for some values of a and b, uniform(a, b) can never produce the
value b?"

I would argue that it is a good thing if uniform never returns b.

alist[ int(uniform(0, len(alist))) ]

can apparently fail for some lists, but not others.

Admittedly, I don't have a good reason for using the above rather than
sample(), or for truncating the result of uniform() rather than using
randrange(). Hopefully if I don't mention it, nobody will notice it...
*wink*

--
Steven

```