Other answers have pointed out that the result of random()
is always strictly less than 1.0
; however, that's only half the story.
If you're computing randrange(n)
as int(random() * n)
, you also need to know that for any Python float x
satisfying 0.0 <= x < 1.0
, and any positive integer n
, it's true that 0.0 <= x * n < n
, so that int(x * n)
is strictly less than n
.
There are two things that could go wrong here: first, when we compute x * n
, n
is implicitly converted to a float. For large enough n
, that conversion might alter the value. But if you look at the Python source, you'll see that it only uses the int(random() * n)
method for n
smaller than 2**53
(here and below I'm assuming that the platform uses IEEE 754 doubles), which is the range where the conversion of n
to a float is guaranteed not to lose information (because n
can be represented exactly as a float).
The second thing that could go wrong is that the result of the multiplication x * n
(which is now being performed as a product of floats, remember) probably won't be exactly representable, so there will be some rounding involved. If x
is close enough to 1.0
, it's conceivable that the rounding will round the result up to n
itself.
To see that this can't happen, we only need to consider the largest possible value for x
, which is (on almost all machines that Python runs on) 1 - 2**-53
. So we need to show that (1 - 2**-53) * n < n
for our positive integer n
, since it'll always be true that random() * n <= (1 - 2**-53) * n
.
Proof (Sketch) Let k
be the unique integer k
such that 2**(k-1) < n <= 2**k
. Then the next float down from n
is n - 2**(k-53)
. We need to show that n*(1-2**53)
(i.e., the actual, unrounded, value of the product) is closer to n - 2**(k-53)
than to n
, so that it'll always be rounded down. But a little arithmetic shows that the distance from n*(1-2**-53)
to n
is 2**-53 * n
, while the distance from n*(1-2**-53)
to n - 2**(k-53)
is (2**k - n) * 2**-53
. But 2**k - n < n
(because we chose k
so that 2**(k-1) < n
), so the product is closer to n - 2**(k-53)
, so it will get rounded down (assuming, that is, that the platform is doing some form of round-to-nearest).
So we're safe. Phew!
Addendum (2015-07-04): The above assumes IEEE 754 binary64 arithmetic, with round-ties-to-even rounding mode. On many machines, that assumption is fairly safe. However, on x86 machines that use the x87 FPU for floating-point (for example, various flavours of 32-bit Linux), there's a possibility of double rounding in the multiplication, and that makes it possible for random() * n
to round up to n
in the case where random()
returns the largest possible value. The smallest such n
for which this can happen is n = 2049
. See the discussion at http://bugs.python.org/issue24546 for more.
int(random.random() * n)
still isn't a perfect way to generate integers that are uniformly distributed inrange(n)
; there's a bias that's insignificant for smalln
but becomes significant asn
becomes large. I've opened a Python bug for this at bugs.python.org/issue9025 – Novocaine