« Previous entry | Next entry » Browse > Snippets

Skip to comments (9) Random numbers with a good uniform distribution
Posted by Erik on Jan 10 2006 @ 14:18  :: 6077 unique visits

C/C++


In lots of projects, including my own old projects, I see people getting random numbers the following way.
number between min and max:
CODE: CPP
number = (rand() % (max - (min - 1))) + min;

This is very wrong because (most of the time) the modulo (%) operator will destroy the uniform distribution of the numers that rand() returnes.

A simple example:
Let's assume the rand() implementation you are using gives you numbers between 0 and 15 (inclusive).
If you would want a number between 0 and 10 this would lead to the following code:
CODE: CPP
number = rand() % 11;

In this case the numbers 0 up to 4 would be returned twice as much as the numbers 5 up to 10.
This because the % 11 will convert the numbers 11 up to 15 into 0 up to 4
11 % 11 = 0
12 % 11 = 1
...


A better method which leaves the distribution in tact is the following:
CODE: CPP
number = (rand() * ((max - min) / RAND_MAX)) + min;

Note: RAND_MAX is a macro in C/C++ which defines the maximum value that can be returned by the rand() function.


PHP


In PHP you can specify a min and max parameter to the rand function. This function returns numbers with a uniform distribution.


Javascript


With javascript the story is a little different. Javascript has the Math.random() function which returns a number between 0 and 1 only never 1 (so 0 >= n < 1). If you would want a number between lets say 0 and 2 most people would write something like this:
CODE: JAVASCRIPT
number = Math.round(Math.random() * 2);


This will randomly return 0, 1 or 2 but the distribution isn't unifom anymore because of the way Math.round() rounds the numbers. The number 1 will be returned twice as much as 0 and 2.
This because the range of numbers which is rounded to 1 is twice as big as for 0 and 2:
0.0 to 0.5 is rounded to 0
0.5 to 1.5 is rounded to 1 and
1.5 to 2.0 is rounded to 2

This can be fixed using Math.floor() which will always round a number to the lowest whole number:
CODE: JAVASCRIPT
number = Math.floor(Math.random() * (max - min + 1) + min);

9 comments posted so far
Add your own »

1. On Jan 10 2006 @ 22:28 guest wrote:

Thank you, this is very useful!

2. On Jan 13 2006 @ 10:06 guest wrote:

see this random number generator.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html

3. On Jan 13 2006 @ 11:02 Erik wrote:

Yes the Mersenne Twister is a good random number generator, most say even better than the default rand() which in most libraries is implemented like this:
CODE: C
static unsigned int seed = 1;

void srand(unsigned int _seed) {
    seed = _seed;
}

int rand(void) {
    seed = seed * 214013 + 2531011;
    return (seed >> 16) & 0x7fff;
}

4. On Jan 14 2006 @ 21:25 Revvy wrote:

I'd love to find out why those magic numbers are used.

5. On Jan 20 2006 @ 16:33 hxa7241 wrote:

number = (rand() * (float(max - min) / RAND_MAX)) + min;

-- you need to force fp evaluation or you always get zero.

Another reason for not using the % form is that it uses the low-order bits of the random number: which are often much less random than the high bits.

9. On Jan 05 2010 @ 14:28 uggbaileybutton wrote:

bailey button uggs

-ugg boots cheap

ugg boots uk

ugg classic

Add a new comment

Name:
Password: (leave empty for anonymous comment)
 
View formatting tags Comment: