Mail Archives: djgpp/2000/05/25/07:31:15
Chris Miller wrote:
>Ideally, I am attempting to generate a random integer between 0 and
>1,000,000.
If you want to be portable, you have to be very careful with such
a large range. RAND_MAX can be as small as 32767 (and often is).
Depending on your problem, I can suggest two solutions. If you
do not need "high-quality" random numbers, you can shift together
two return values of rand(). Of course, much care has to be taken,
because RAND_MAX+1 is not guaranteed to be a power of two.
The other solution is to write your own PRNG or load it from the
net. (You could do a web-search for Mersenne Twister.)
A not too bad and portable PRNG is the following, originally
suggested by George Marsaglia. It will return pseudo random numbers
between 0 and 0xffffffffUL (both inclusive).
static unsigned long zs = 1234567UL;
static unsigned long ws = 7654321UL;
/* Combine two multiply with carry PRNGs */
unsigned long mwc1616(void)
{
unsigned long t = zs;
zs = 30903*(t&0xffffUL)+(t>>16);
t = ws;
ws = 18000*(t&0xffffUL)+(t>>16);
return ((ws<<16)&0xffffffffUL) + (zs&0xffffUL);
}
void seed_mwc1616(unsigned long s)
{
s &= 0xffffffffUL; /* Mask for portablity to 64bit long */
if (s == 0)
s = 1234567UL;
zs = s;
ws = 7654321UL;
}
Then your random number between 0 an 1,000,000 (inclusive) would be
unsigned long r = (unsigned long)((mwc1616()/4.294967296e9) * 1000001.0);
/* or mwc1616() * 2.3283064365386962890625e-10 * 1000001.0 */
/* or mwc1616() * 2.3283087648451328277587890625e-4 */
Note, that this method won't generalize to a larger range. Then
more sophisticated methods would be needed. For your special
problem, the method will return some numbers with a probability
of floor(2^32/1000001)/2^32 = 0.9997748e-6 and the other numbers with a
probability of ceil(2^32/1000001)/2^32 = 1.0000076e-6. This small
difference should be ok for many purposes. In general, the larger
the range, the larger will be the difference in the probabilities
(unless the range is a power of two).
Of course, when you are interested in DJGPP only, you can write
int r = (int)(rand() * 1000001.0)/(RAND_MAX+1.0);
--
Regards, Dieter Buerssner
- Raw text -