Random Numbers ...

Wen-King Su wen-king at cit-vlsi.Caltech.Edu
Thu Feb 25 12:21:38 AEST 1988


In article <7097 at sol.ARPA> crowl at cs.rochester.edu (Lawrence Crowl) writes:
<#define NEGABS( i ) ((i) > 0 ? -(i) : (i))
>short rand16mod( modulus )
<    short modulus ;
>    {
<    seed16 = (short)(seed16 * 25173) + 13849 ;
>    return (short)NEGABS(seed16) / (short)(-32768 / modulus) ;
            ^^^^^^^^^^^^^^^^^^^^^
Don't do this.  Now you have a random number source that does not have
an uniform distribution; both '0' and MAX_NEGATIVE occur at half the
frequency as the other numbers.  Use unsigned integers instead.

Even if the random source is uniform over a range, say R, you can't
expect the the result of a simple division to yield another uniform
distribution unless R is a multiple of the divisor.  For example,
suppose the random source has a range of 0-7, and the divisor happens
to be 3 (so that you get the numbers 0, 1, an 2 randomly).

  0 / 3 -> 0
  1 / 3 -> 0
  2 / 3 -> 0
  3 / 3 -> 1
  4 / 3 -> 1
  5 / 3 -> 1
  6 / 3 -> 2
  7 / 3 -> 2  <-- 2 only appear twice.

In general, the correct way to do it is to use a random number generator
of an appropriate range (the smallest power of 2 that is large enought to
cover all the numbers you need).  Then keep pulling numbers from the
genenerator until you get the ones that falls in your range.

unsigned my_random_source();

my_random(range)
    int range;
{
    int value;

    do { value = my_random_source(); } while(value >= range);

    return(value);
}
/*------------------------------------------------------------------------*\
| Wen-King Su  wen-king at vlsi.caltech.edu  Caltech Corp of Cosmic Engineers |
\*------------------------------------------------------------------------*/



More information about the Comp.lang.c mailing list