The most un-biased method of doing it is to use the rejection method. This is as follows:
Code:
// Generates random number between min and max, inclusive.
int random(int min, int max)
{
int range, result, cutoff;
if (min >= max)
return min; // only one outcome possible, or invalid parameters
range = max-min+1;
cutoff = (RAND_MAX / range) * range;
// Rejection method, to be statistically unbiased.
do {
result = rand();
} while (result >= cutoff);
return result % range + min;
}
The theory with the rejection method is easier to understand if you imagine a random number generator that generates a 4-bit random number and you want a random number with six equally probably outcomes (say for a die roll).
Throwing away the loop and using % alone, you get:
- 0 if rand() was 0, 6, or 12
- 1 if rand() was 1, 7, or 13
- 2 if rand() was 2, 8, or 14
- 3 if rand() was 3, 9, or 15
- 4 if rand() was 4 or 10
- 5 if rand() was 5 or 11
Notice how there are three ways to get 0-3 but only two ways of getting 4-5. This is statistically biased towards the lower numbers! So the rejection method would throw away any random number of 12 or above and try again. That way there are exactly two ways of arriving at each outcome. (The calculation for cutoff calculates 12 in this case due to the integer division result of 16 / 6 being 2, and 2 * 6 = 12)
About the loop:
Here it is ignoring 4 values out of 16 so it will loop around again 1/4th of the time, but in a real situation it loops so few times you do not have to worry about it. E.g. when getting a random number for a die roll using random number generator that gives a 15-bit output, it loops only 4 out of 32767 times. That's small enough that you don't need to worry about it. The chance of that looping even 4 times is 0.000000000018%
Last but not least, make sure that you call srand only once in your program, preferably inside main.