Others have already pointed out the some things about the coding style. Following their advice, you will be on par with more professional C code. Unfortunately, that will still not give you good random numbers.
Now, depending on what you want to do, that might not be too bad, but I still wanted to point it out. The C function rand
is (are) a very very bad random number generator. Given only few (full) outputs, one can already deduce some information about the next numbers.
Also srand(time(NULL));
is a relatively bad seed. Running the program on two different computers but at the same time (in seconds!) will result in identical numbers. Running the program in short succession will result in similar numbers.
Furthermore, rand() % 10
will not create evenly distributed numbers. RAND_MAX
is usually not divisible by 10, so the lower numbers will be more likely than 8 or 9. This is even more pronounced when you want to draw numbers from a larger range. RAND_MAX
is often only of the order of 32k, so drawing numbers in a range of 1-2000 or similar will already be significantly skewed towards the lower numbers.
tl;dr If the random numbers are not important (e.g. a computer game), everything should be fine. If you ever want to do numerics or cryptography, then do not use rand()
.
edit: It is somewhat difficult to get good random numbers in C...
If you want to do cryptography then read /dev/random
on linux systems (note that under OSX /dev/random
is not cryptographically secure!) or call CryptGenRandom
on windows systems. Both will deliver 'true' random numbers. For numerics you can (for example) use a Mersenne Twister (creative-commons code on the wikipedia) and seed it with true random numbers or with (preferably a hash of) the current time in nanoseconds.
In either case you still have to do some work to get a uniform distribution over any given range. A simple but ineffective method simply draws a new random number when needed
/// @arg (*random) - a function providing (pseudo) random unsigned numbers
/// @arg randMax - the largest number that can be returned by (*random)
/// @arg rangeMax - the largest desired number
/// @returns a uniformly random number in [0, rangeMax]
unsigned uniform(unsigned (*random)(void), unsigned randMax, unsigned rangeMax) {
if (rangeMax <= randMax) {
// the following assumes, that both maxima are smaller than 2^32-1
randMax += 1;
rangeMax += 1;
unsigned cutoff = (randMax / rangeMax) * rangeMax;
unsigned result = random();
while (result >= cutoff) {
result = random();
}
return result % rangeMax;
} else {
// more complicated code or error
}
}
If you do not want to throw away any random numbers that you sampled you will have to manage some internal state. This quickly becomes complicated and is beyond the scope of this answer.
rand()
or are you trying to roll "fairly" and keep count to see how much it varies from an even distribution? \$\endgroup\$rand()
+srand
. There is the modulo bias @Edward mentioned, but it's small compared to the effect ofrand
sucking. \$\endgroup\$