(*# check(stack=>off, index=>off, range=>off, overflow=>off, nil_ptr=>off) *) IMPLEMENTATION MODULE Rand; (******************************************************************************) (* Modify by John McMonagle 4/19/88 *) (* MODULA-2 Library *) (* *) (* LOGITECH SA, CH-1111 Romanel (Switzerland) *) (* LOGITECH Inc, Fremont, CA 94555 (USA) *) (* *) (* Module : Random, random number generator *) (* *) (* Release : 3.0 - July 87 *) (* *) (* Copyright (C) 1987 Logitech, All rights reserved *) (* *) (* Permission is hereby granted to registered users to use or abstract *) (* the following program in the implementation of customized versions. *) (* This permission does not include the right to redistribute the *) (* source code of this program. *) (* *) (******************************************************************************) (*---------------------------------------------------------------------------- Algorithm: Additive congruential method (D.Knuth) ----------------------------------------------------------------------------*) (*/NOCHECK:O *) FROM EnvironUtils IMPORT GetTime; FROM NumTypes IMPORT Real8; CONST C = 53;(* was54 *) R = 65536.0; VAR a : ARRAY [0 .. C] OF CARDINAL; j, k : [0 .. C]; PROCEDURE Next (): CARDINAL; BEGIN INC(a [k], a [j]); IF k = 0 THEN k := C; ELSE DEC(k); END; IF j = 0 THEN j := C; ELSE DEC(j); END; RETURN a [k]; END Next; PROCEDURE RandomInit (seed : CARDINAL); VAR i, dummy : CARDINAL; BEGIN j := 23;(* was 24 *) k := 0; FOR i := 0 TO C DO a [i] := 0; END; a [k] := 31415 + seed; IF a [k] = 0 THEN a [k] := 31415; END; (* added 4/19/88 make sure seed is odd or all will be even *) IF NOT ODD(a[k]) THEN INC(a[k]); END; FOR i := 0 TO 1219 DO(* was 1999 reduced as precision is not required *) dummy := Next (); END; END RandomInit; PROCEDURE RandomCard (bound : CARDINAL): CARDINAL; BEGIN IF bound = 0 THEN RETURN Next (); ELSE RETURN Next() MOD bound; (* RETURN TRUNC (FLOAT (bound) * FLOAT (Next ()) / R); *) END; END RandomCard; PROCEDURE RandomInt (bound : INTEGER): INTEGER; BEGIN RETURN INTEGER (RandomCard (CARDINAL (ABS (bound)))); END RandomInt; (* PROCEDURE RandomReal () : Real8; BEGIN RETURN VAL(Real8,RandomCard (10000)) * 1.0E-16 + VAL(Real8,RandomCard (10000)) * 1.0E-12 + VAL(Real8,RandomCard (10000)) * 1.0E-08 + VAL(Real8,RandomCard (10000)) * 1.0E-04; END RandomReal; *) PROCEDURE Randomize; VAR minute,second,hundredths, i, j : CARDINAL; dummy: CARDINAL; str: ARRAY[0..40] OF CHAR; BEGIN GetTime(dummy,minute,second,hundredths,str); RandomInit (hundredths*second); j := minute; FOR i := 0 TO j DO dummy := Next (); END; END Randomize; BEGIN Randomize; (* FOR j:=0 TO C DO a[j]:=0; END; j:=0; k:=0; *) END Rand.