Article View: net.lang.mod2
Article #418random number generator for Logitech
From: Daniel M. Frank
Date: Mon, 12 May 1986 22:56
Date: Mon, 12 May 1986 22:56
145 lines
3961 bytes
3961 bytes
Here is a random number generator my partner and I used for a simulation
project last spring. It's not terribly good, but the distributions seemed
adequate for what we were doing (and we did run some tests). Actually, we
built a pretty nifty simulation system using processes, with interprocess
communication via mailboxes. Worked fine, although a bit slow (on an XT).
#!/bin/sh ----cut here-----cut here-----cut here-----cut here-----
# This is a shell archive.
# Run the following text with /bin/sh to extract.
YASASTART=`pwd`
cat - << \Funky!Stuff! > rand.def
DEFINITION MODULE Rand;
EXPORT QUALIFIED
Random ;
PROCEDURE Random (): REAL;
END Rand.
Funky!Stuff!
cat - << \Funky!Stuff! > rand.mod
IMPLEMENTATION MODULE Rand;
CONST
MAXINT = 32767; (* ? *)
DEFAULTSEED = 7321;
NUMCALLS = 4;
VAR
a : ARRAY[0..54] OF INTEGER;
seed, maxRand: INTEGER;
p, range: INTEGER; (* p indexes into array a of random #'s, range
is range of numbers in array *)
(***************************************************************)
PROCEDURE RandGen();
VAR
i, ran: INTEGER;
BEGIN
FOR i := 0 TO 23 DO
ran := a[i] - a[i + 31];
IF ran < 0 THEN
INC(ran,maxRand);
END;
a[i] := ran;
END;
FOR i := 24 TO 54 DO
ran := a[i] - a[i - 24];
IF ran < 0 THEN
INC(ran,maxRand);
END;
a[i] := ran;
END;
END RandGen;
(*******************************************************************)
PROCEDURE InitRandom(VAR iRange, iSeed: INTEGER): INTEGER;
VAR
m, i, j, minSeed, maxSeed: INTEGER;
f, fPrev, fTmp: INTEGER; (* for computing Fibonacci numbers *)
BEGIN
(* Set the range and the window for legal seed values *)
IF iRange <= 0 THEN
iRange := MAXINT;
END;
minSeed := iRange DIV 10;
maxSeed := iRange - minSeed;
maxRand := iRange;
(* Set the first seed value *)
iSeed := DEFAULTSEED;
WHILE (iSeed < minSeed) DO
iSeed := iSeed * 3;
END;
WHILE (iSeed > maxSeed) DO
iSeed := iSeed DIV 3;
END;
(* Scatter other values through the array to get things started.
The values are (-1)^i * (iSeed*F(i-1) - F(i)) MOD MAXINT, 0<i<55,
where F(i) is the ith Fibonacci number. Scale the results to lie in
[0,maxRand). Then bake a few batches of random numbers to make things
even more random. *)
fPrev := iSeed;
a[0] := iSeed MOD maxRand;
f := 1;
FOR i := 1 TO 54 DO
j := (21 * i) MOD 55;
a[j] := f MOD maxRand;
m := a[j];
fTmp := f; f:= fPrev - f; fPrev := fTmp;
IF (f < 0) THEN
INC(f, MAXINT);
END;
END;
FOR i:= 1 TO NUMCALLS DO
RandGen();
END;
p := 54;
RETURN (iSeed);
END InitRandom;
(***************************************************************)
PROCEDURE RandomInt(seed: INTEGER): INTEGER;
BEGIN
DEC(p);
IF p < 0 THEN
RandGen();
p := 54;
END;
RETURN (a[p]) ;
END RandomInt;
(*******************************************************************)
PROCEDURE Random(): REAL;
VAR
rNum: REAL;
i: INTEGER;
BEGIN
i := RandomInt(seed);
rNum := FLOAT(i) / FLOAT(MAXINT) ;
RETURN (rNum);
END Random ;
BEGIN
range := 0; seed := 0;
seed := InitRandom(range, seed);
END Rand .
Funky!Stuff!
Technical Details
Message-ID:
<8605122256.AA09131@caseus.wisc.edu>Path:
arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!ucbvax!CASEUS.WISC.EDU!danShow Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site ucbvax.BERKELEY.EDU Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!ucbvax!CASEUS.WISC.EDU!dan From: dan@CASEUS.WISC.EDU (Daniel M. Frank) Newsgroups: net.lang.mod2 Subject: random number generator for Logitech Message-ID: <8605122256.AA09131@caseus.wisc.edu> Date: Mon, 12-May-86 18:56:50 EDT Article-I.D.: caseus.8605122256.AA09131 Posted: Mon May 12 18:56:50 1986 Date-Received: Wed, 14-May-86 12:52:54 EDT Sender: daemon@ucbvax.BERKELEY.EDU Organization: The ARPA Internet Lines: 145