Mail Archives: djgpp/1996/08/29/19:26:57
In article <3225ABDD DOT 7AF48E03 AT alcyone DOT com> Erik Max Francis <max AT alcyone DOT com> writes:
>J.J. Pierson wrote:
>> Silly question... How would I go about getting a random number from say 1
>> to a specified number?
>For a number between 1 and n, use
> rand()%n + 1.
>If n is an even power of 2, then bitwise-anding a mask will be faste:
> rand()&(n - 1) + 1.
You'd be suprised at how bad these two methods are, especially with
rand(). If you're using any congruential RNG you'll have to expect the
lower bits to contain lots of nasty patterns.
A better plan in certain circumstances is to either use a different RNG
(RC4 is wonderful, and very simple) or set up your conditions a little
better. For example, if speed isn't an issue, try
rand()/(float)UINT_MAX * n
If speed is an issue, but you only need a certain range of n, try
// throw away as many bad bits as you can afford,
// never more than the maximum place value of your n;
// for this example, n must be < 32.
r = rand() >> 5;
// factor the n into the equation
r = r*n;
// finally, divide the rest of the bits out, leaving
// only the random bits affected by n.
r = r >> (32-5);
This gives approximately the same results within its range as the floating
point method, but is faster. The more bits you can throw away (the
number 5 in this example) the better for a congruential RNG, such as
ANSI C uses.
If it was up to me, I'd use RC4. I've developed a distrust of
congruential RNGs, even Berkeley's random().
>Erik Max Francis, &tSftDotIotE http://www.alcyone.com/max/ max AT alcyone DOT com
-Billy
- Raw text -