Dunno whether you care that much (many people don't care), but
rand() % max
is
not really random for almost all values of max. To be precise: for all max except when they are a power of two (max = 1,2,4,8,16...)
This is because rand returns a random from 0 to RAND_MAX (which is usually 32767), so first of all it will never return anything bigger than RAND_MAX. But even for smaller values, you get some numbers much more often then other numbers. This problem is worse, the bigger "max" is.
Easiest to get a grasp of "why???" is: What if RAND_MAX would be 2 and you do rand()%2, then you get:
rand() returns 0 -> 0
rand() returns 1 -> 1
rand() returns 2 -> 0
so you get 0 twice as much as 1. Not particular random...
This a nice piece of code to try it out for yourself:
1 2 3 4 5 6 7 8 9 10 11 12
|
int main()
{
int count = 0;
int max = RAND_MAX/2;
int number_of_tests = 10000000;
for (int i = 0; i < number_of_tests; ++i)
if ((rand() % max) == 0)
count++;
cout << "Actual: " << count << endl;
cout << "Expected: " << (number_of_tests/max) << endl;
}
|
You count the numbers of zeroes. Should be one out of "max" times, right? Wrong! You'll be surprised.. ;-).
What is better? Well, I use this:
1 2 3 4 5 6 7
|
int better_rand(int max)
{
int r,x = 1;
while (x < max) x <<= 1;
while ((r = rand() % x) > max);
return r;
}
|
not the fastest, but doesn't have the issues with "rand() % max". If you want industrial strength random stuff in your game, forget about std::rand() at all...
And upcoming standard library will fix these problems anyway, by providing a fully fledged random number generator system.. ;-)
Ciao, Imi.
Edit: Just remembered: Beware, my better_rand returns values from 0 to max includive, whereas rand() % max does never result in "max". To get the same as rand()%max, change the second while to "...>= max..."