When using random, which form returns an equal 50% chance?

I’m guessing that most built in random generators return something like this:

[0.0, 1.0)

so if I would like a 50% chance would I use something like this:

if random() < .5

or something like:

if random() <= .5

Thanks for the help.

Ah, the old “.5” problem. Here’s the answer:

If you’re going to divide 10 things into two equal parts, you need 5 things in each part. 0 thru 4 in the first part, 5-9 in the second part. So… < .5 is correct.

Why do it yourself? Python has random.choice 🙂

random.choice([0, 1]) will give you 0/1 with equal chances — and it is a standard part of Python, coded up by the same people who wrote random.random (and thus know more about its semantics than anyone else)

To a first approximation, either works.

The best way is to choose a random generator that specifically emits booleans or integers with range. Then you can nail the range exactly.

Operations like “equality” with floating point is iffy anyway.

 if random() < .5

In binary, .5 is .10000000000….
So, basically, the question reduces to, “What is the first binary digit after the radix point… 0 (for <.5) or 1 (for .5 or more) ?”

For a particular system you should test it, if you really want to find out. Could take a while though 🙂

I agree with the other posters that to the first order, it doesn’t matter. If it does matter, you’ll need a better RNG anyway.

EDIT: I just tried the default RNG in C# with 1,000,000,000 attempts and the answers were identical…

import random
def fifty_fifty():
    "Return 0 or 1 with 50% chance for each"
    return random.randrange(2)

< .5

but that assumes that your floating point support is good enough to satisfy your precision demands (since it’s never exactly).

If I want 50% chance, I’d just check for the LSB (Least Significant Bit).

If you’re going to be that fussy about your random numbers, don’t rely on anything that comes built-in. Get a well-documented RNG from a place you trust (I trust Boost, for what that’s worth), and read the documentation. It used to be that standard RNGs were notoriously bad, and I still wouldn’t trust them.

Alternately, use an integer RNG that gives you discrete values within a range, and divide the range in half. RNGs, in my experience, are integral, and the floating-point function simply divides by the top of the range.

Of course, if this is true, you’ve got your answer. If the integer RNG produces 0, 1, 2, and 3, the floating-point equivalent will be 0.0, 0.25, 0.5, and 0.75, so the answer is to test < 0.5.

If the RNG isn’t based on integral calculations, then it’s based on floating-point calculations, and hence is inexact. In that case, it doesn’t matter whether you test <= or <, since there is no guarantee that a calculation that should be a precise 0.5 will be.

So, the answer is probably to test < 0.5, which will likely be the correct one if it makes a difference.

If you need truly random numbers, you can try random.org. They offer a web service connected to a device that detects noise coming from the universe. Still not random technically speaking, but close enough I guess.

They have all sort of way to make the query such as black and white images.

This is the version I like to use:

import random

# Returns True 50% of the time. 
def fifty_fifty():
    if random.random() < .5:
        return True
    return False

Usage:

if fifty_fifty():
    # Do something half the time
else:
    # Do something else instead half the time

It doesn’t matter. Both formulas yield the desired result.

Leave a Comment