random number between -maxint and +maxint

Tim Peters tim.one at home.com
Sun Mar 11 23:22:03 EST 2001


[Dan Parisien]
> I can't figure out a good way to do it, does anyone know a better solution
> than
>
> from whrandom import whrandom
> rand = whrandom()
> max = 2**30 + (2**30-1) #one less than 2**31
> randomnumber = rand.randrange(0, max) - rand.randrange(0, max)

The last line is clearly biased; e.g., consider what happens if max is 2:

    LHS  RHS  result
      0    0       0
      0    1      -1
      1    0       1
      1    1       0

That is, not all results are equally likely.  Try instead:

    import sys, random, math
    nvalues = 2.0 * sys.maxint + 1
    raw = random.random() * nvalues - sys.maxint
    randomnumber = int(math.floor(raw))

If maxint is 2 there, then nvalues is 5., random.random()*nvalues is uniform
across [0., 5.); that minus maxint is uniform in [-2., 3.); so the floor is
uniform in [-2., -1., 0., 1., 2.] == -maxint thru maxint inclusive.

Somewhat simpler, if you're assuming you're on a 32-bit box, is:

    (random.randrange(65536) << 16) | random.randrange(65536)

If you're afraid of getting -sys.maxint-1, stick that in a loop and keep
going until you get something else.

even-simpler-hardwire-the-result-to-6<wink>-ly y'rs  - tim





More information about the Python-list mailing list