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