delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/05/05/23:14:38

From: mert0407 AT sable DOT ox DOT ac DOT uk (George Foot)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Random generator?
Date: 3 May 1997 19:54:49 GMT
Organization: Oxford University, England
Lines: 51
Message-ID: <5kg569$d1@news.ox.ac.uk>
References: <2 DOT 2 DOT 32 DOT 19970429193847 DOT 006a0ec4 AT gate72> <33665CFB DOT C26 AT cs DOT com> <5kdhou$o9r$1 AT pike DOT dnaco DOT net>
NNTP-Posting-Host: sable.ox.ac.uk
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Eric Heft (eheft AT dnaco DOT net) wrote:

: Somthing like this gets rid of this problem. 

: int rnd(int lo,int hi)
: {
:    int rng = hi - lo + 1;
:    return ( lo + rng * rand() / MAX_INT );
: }

I'm not so sure... does this not overflow if rand() returns close to
MAXINT? Replacing rand() with a function returning close to MAXINT results
in incorrect output.

I seem to remember discussing this here before, but IMHO the best solution
is something like:

int rnd(int lo,int hi)
{
 int x;
 do {
  x=random();
 } while ((x<lo)||(x>=hi)); 
 return x;
}

or equivalent. This could potentially be a lot slower, though, depending
how large your range is; perhaps a better replacement would be:

int rnd(int lo,int hi)
{
 int max,x,y;
 max=hi-lo;
 if (max&(max-1)) {           /* returns true if max is not a power of two */
  x=((unsigned)MAXINT+1)/max; /* this is the number of times our range 
                                 fits into [0,MAXINT]                      */
  x*=max;
  do {
   y=random();
  } while (y>=x);
 } else {
  y=random();
 }
 return (lo+(y%max));
}

I think that's right...

-- 
George Foot <mert0407 AT sable DOT ox DOT ac DOT uk>
Merton College, Oxford

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019