Completely random distribution of numbers

I'm looking to code a completely random distribution of numbers that doesn't affect performance using rand. I believe this code would be ideal but I don't understand how to use it. Where would I input the range of numbers and the quantity? Thanks in advance!
1
2
3
4
double uniform_deviate ( int seed ){
	return seed * ( 1.0 / ( RAND_MAX + 1.0 ) );
}
int r = M + uniform_deviate ( rand() ) * ( N - M );


And for the seed...
1
2
3
4
5
6
7
8
9
10
unsigned time_seed(){
	time_t now = time ( 0 );
	unsigned char *p = (unsigned char *)&now;
	unsigned seed = 0;
	size_t i;
	for ( i = 0; i < sizeof now; i++ )
		seed = seed * ( UCHAR_MAX + 2U ) + p[i];
	return seed;
}
srand ( time_seed() );
Last edited on
Where would I input the range of numbers and the quantity?

The range is indicated by N and M here:

int r = M + uniform_deviate ( rand() ) * ( N - M );


M would be the minimum number
N would be the maximum (exclusive)


As for quantity, you'd just put this in a loop and generate as many numbers as you want by doing this repeatedly. (note: not the srand/seeding stuff... that'd you'd only do once.. but the rand() stuff you would do repeatedly)

I'm looking to code a completely random distribution of numbers that doesn't affect performance using rand. I believe this code would be ideal


It's really not.

For one thing... scrambling the seed you give to srand does nothing to improve randomness... it's just unnecessary complication.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// this:
unsigned time_seed(){
	time_t now = time ( 0 );
	unsigned char *p = (unsigned char *)&now;
	unsigned seed = 0;
	size_t i;
	for ( i = 0; i < sizeof now; i++ )
		seed = seed * ( UCHAR_MAX + 2U ) + p[i];
	return seed;
}
srand ( time_seed() );


// is really no better than this:
srand( (unsigned)time(0) );


Furthermore... rand() produces a finite integral set. Converting those integers to a double does not magically make the set infinite. So any linear conversion is going to have bias towards some numbers.

Say for example... RAND_MAX is 9... meaning RAND produces numbers [0,9]
And let's say you want a random number between [0,2]

Using the typical rand() % 3 approach, you get this:


rand() output -> final output
---------------------
0 -> 0
1 -> 1
2 -> 2
3 -> 0
4 -> 1
5 -> 2
6 -> 0
7 -> 1
8 -> 2
9 -> 0


Notice here you have a bias towards 0, as it is produced more often than other numbers.

Now let's take a look at the convert-to-double-and-scale-down approach as illustrated by your code. IE: uniform_deviate ( rand() ) * 3;

0 -> 0
1 -> 0
2 -> 0
3 -> 0
4 -> 1
5 -> 1
6 -> 1
7 -> 2
8 -> 2
9 -> 2


So you still have bias towards 0. The only difference is the distribution (which is supposedly random anyway).

So really... your big old complicated way of producing numbers is no better than the usual:

 
rand() % x


It's just slower and more confusing.





Of course... C++11 already solved these problems with better RNGs and distribution mechanisms. If you can use C++11, and you are that concerned about getting good distribution...look at the <random> header.
Last edited on
Appreciate it man, I'll check out that header!
Topic archived. No new replies allowed.