double r; /* random value in range [0,1) */
double x; /* random value in range [0,M) */
long int M; /* user supplied upper boundary */
int y; /* random integer in range [0,M) if M is an integer then range = [0,M-1] */
int z; /* random integer in range [1,M+1) if M is an integer then range = [1,M] */
srand( (unsigned int)time(0) );
r = ( (double)rand() / ((double)(RAND_MAX)+(double)(1)) );
/* r is a random floating point value in the range [0,1) {including 0, not including 1}. Note we must convert rand() and/or RAND_MAX+1 to floating point values to avoid integer division. In addition, Sean Scanlon pointed out the possibility that RAND_MAX may be the largest positive integer the architecture can represent, so (RAND_MAX+1) may result in an overflow, or more likely the value will end up being the largest negative integer the architecture can represent, so to avoid this we convert RAND_MAX and 1 to doubles before adding. */
x = (r * M);
/* x is a random floating point value in the range [0,M) {including 0, not including M}. */
y = (int) x;
/* y is a random integer in the range [0,M) {including 0, not including M}. If M is an integer then the range is [0,M-1] {inclusive} */
z = y + 1;
/* z is a random integer in the range [1,M+1) {including 1, not including M+1}. If M is an integer then the range is [1,M] {inclusive} */
We can combine the above equations to create formulas for r,x,y,z:
r = [0,1) = {r: 0 <= r < 1} real
x = [0,M) = {x: 0 <= x < M} real
y = [0,M) = {y: 0 <= y < M} integer
z = [1,M] = {z: 1 <= z <= M} integer