Path: utzoo!mnetor!uunet!lll-winken!lll-lcc!ames!elroy!cit-vax!cit-vlsi!wen-king From: wen-king@cit-vlsi.Caltech.Edu (Wen-King Su) Newsgroups: comp.lang.c Subject: Re: Random Numbers ... Message-ID: <5555@cit-vax.Caltech.Edu> Date: 25 Feb 88 02:21:38 GMT References: <11972@brl-adm.ARPA> <7097@sol.ARPA> Sender: news@cit-vax.Caltech.Edu Reply-To: wen-king@cit-vlsi.UUCP (Wen-King Su) Organization: California Institute of Technology Lines: 45 In article <7097@sol.ARPA> crowl@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@vlsi.caltech.edu Caltech Corp of Cosmic Engineers | \*------------------------------------------------------------------------*/