1 ///Copyright Paul Reiche, Fred Ford. 1992-2002
2 
3 /*
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19  /****************************************************************************
20 * FILE: random.c
21 * DESC: a library of random number generators for general purpose use.
22 *
23 * References:
24 * "Random Number Generators: Good ones are hard to find" S.K.Park & K.W.Miller
25 * Communications of the ACM, Vol31 Number 10, October 1988, Pp 1192-1201
26 *
27 * HISTORY: Created 1/23/1989
28 * LAST CHANGED:
29 *
30 * Copyright (c) 1989, Robert Leyland and Fred Ford
31 ****************************************************************************/
32 
33 /* ----------------------------INCLUDES----------------------------------- */
34 #include "mthintrn.h" /* get the externs for error checking */
35 
36 /* ----------------------------DEFINES------------------------------------ */
37 /* constants for licongruential random number generator from CACM article
38    referenced above */
39 #define A 16807 /* a relatively prime number -- also M div Q */
40 #define M 2147483647L /* 0xFFFFFFFF / 2 */
41 #define Q 127773L /* M div A */
42 #define R 2836 /* M mod A */
43 
44 /* ----------------------------STATIC DATA-------------------------------- */
45 
46 static DWORD seed = 12345L; /* random number seed */
47 
48 /* ----------------------------CODE--------------------------------------- */
49 
50 /*****************************************************************************
51 * FUNC: DWORD TFB_Random()
52 *
53 * DESC: random number generator
54 *
55 * NOTES:
56 *
57 * HISTORY: Created By Robert leyland
58 *
59 *****************************************************************************/
60 
61 DWORD
TFB_Random(void)62 TFB_Random (void)
63 {
64 	seed = A * (seed % Q) - R * (seed / Q);
65 	if (seed > M)
66 		return (seed -= M);
67 	else if (seed)
68 		return (seed);
69 	else
70 		return (seed = 1L);
71 }
72 
73 /*****************************************************************************
74 * FUNC: DWORD TFB_SeedRandom(DWORD l)
75 *
76 * DESC: set the seed for the random number generator to parameter "l", and
77 * return the value of the previously active seed, to allow for multiple
78 * random number streams.
79 *
80 * NOTES: if the seed is not valid it will be coerced into a valid range
81 *
82 * HISTORY: Created By Robert leyland
83 *
84 *****************************************************************************/
85 
86 DWORD
TFB_SeedRandom(DWORD new_seed)87 TFB_SeedRandom (DWORD new_seed)
88 {
89 	DWORD old_seed;
90 
91 	/* coerce the seed to be in the range 1..M */
92 	if (new_seed == 0L) /* 0 becomes 1 */
93 		new_seed = 1;
94 	else if (new_seed > M) /* and less than M */
95 		new_seed -= M;
96 
97 	old_seed = seed;
98 	seed = new_seed;
99 	return (old_seed);
100 }
101 
102