# [SciPy-user] random number

Robert Kern rkern at ucsd.edu
Tue Jun 29 16:34:32 CDT 2004

```Steve Schmerler wrote:

[snip]

[Gary Pajer:]
>>I was going to suggest random()*1e39,   but it seems that that is not
>>really what you want.
>
>
> Yes. The problem is that the minimal random numbers are mostly only 1e1
> smaller (1e199) than the max value (1e200 in my case).

In [9]: a = stats.uniform.rvs(0,1e200,size=1000)

In [10]: min(a)
Out[10]: 8.4753666305914514e+196

In [11]: max(a)
Out[11]: 9.9870741367340092e+199

Works as expected for me.

>>A uniformly distributed collection of numbers between (0, 1e38) is going
>>to have very few members between (0, 1e3).   Or  (0, 1e24).   Or (0,
>>1e35).    Only 1 in 10 will be in the range (0, 1e37).    It sounds like
>>you may be looking for logarithmically distributed numbers.
>>
>>How about 10**x  where x is a random number in (0, 38).
>>
>
>
> Yeah, I tried something similar:
>
>     import random
>     from Numeric import *
>     def alloverRand(min, max):
>         # e.g. max = x*10**y = exp(max_exponent)
>         max_exponent = log(max)
>         return exp(random.uniform(.1*max_exponent,max_exponent))
>
> This gives log-like distribution. Though it's not uniformly I'll test if it
> works since it covers _all_ numbers from (nearly 0) to 'max'.

Getting pseudo-random numbers over such a large range leaves gaping
holes no matter what you do. Double precision will only get you 1e16ish
possible numbers. Uniform rvs just spreads out the holes mostly evenly
across the whole range. The exponential distribution puts those holes
mostly out near the large end. If you want the orders of magnitude to be
distributed evenly, then that's what you'd use. If you want the values
themselves to be distributed evenly, then you will have to live with the
fact that, with a perfect RNG, the probabilities of generating small
numbers like 1e23, 1e45, and 1e2 from a range of 1e200 in your lifetime
are too small. With a finite precision PRNG, most orders of magnitude
are impossible to achieve:

In [19]: machar_double.epsilon * 1e200
Out[19]: 2.220446049250313e+184

The smallest exponent you can expect is 184.

So I guess my question is, "Can you do anything to reduce the range to
something reasonable?"

--
Robert Kern
rkern at ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

```