In the program below what is the difference between rand and srand? My book says that rand returns an int between 0 and RAND_MAX, which is never smaller than 32,767. Yet this code returns a number from 1-6, how is that? I see the line ( rand() % 6 ) + 1 but I don't see how that would give a number from 1-6.

In the program below what is the difference between rand and srand?

rand generates a pseudorandom number. srand seeds the generator that rand uses. The seed essentially determines what the first random number will be and affects subsequent numbers in the sequence. If you don't call srand, the seed is always 1, so the sequence you get will be predictable.

Yet this code returns a number from 1-6, how is that?

Take any number between 0 and 32767, then apply modulo 6. This will force the number into the range of [0,5]. 1 is added to shift the range to [1,6]. You can play with the idea using a calculator, it's simple math. :)

Note that this is a naive technique for fitting the result of a random number generator into the range you want. It's weak because it severely damages the distribution of random numbers, but that's sometimes acceptable.

severely damages the distribution of random numbers

@deceptikon, is that still the case on most modern implementations? As I understand it, it is now more a function of the modulo divisor and the number of times you want to get a random sample.

High modulo divisor with low number of samples is less uniform distribution; but the lower the modulo divisor and higher the number of samples the more uniform the distribution becomes.

With a sufficient RAND_MAX (i.e. 32 bits) there isn't much of a measurable difference as the number of samples grows.

Yeah, on most systems nowadays you can get away with modulus. But I've been burned by that kind of assumption when porting between different systems before, so personally I would rather divide. Or just use <random> now.

@deceptikon, is that still the case on most modern implementations?

Yes. In the past the biggest problem with modulo (where small ranges were concerned) was an artifact of low order bits not being as "random", and that's largely been fixed in modern implementations. But the distribution problem remains since it's more of a fundamental mathematical thing; pigeonholing a larger range into a smaller range can be tricky.

A better approach in terms of distribution (assuming the generator gives you a uniform distribution within its natural range) would be something more like this:

int r;

do
    r = rand();
while (!inrange(r, min, max));

With this you're working within the uniform distribution rather than fighting against it.

High modulo divisor with low number of samples is less uniform distribution; but the lower the modulo divisor and higher the number of samples the more uniform the distribution becomes.

True. But typically when you care about the distribution, any bias tends to be too much. ;)

This article has been dead for over six months. Start a new discussion instead.