home *** CD-ROM | disk | FTP | other *** search
- package RANDOM is
- --------------------------------------------------------------------------
- --| BEGIN PROLOGUE
- --| DESCRIPTION : Package RANDOM contains the function NUMBER
- --| : which returns a pseudo-random number
- --| : of type FLOAT in the range 0.0 .. 1.0.
- --| :
- --| REQUIREMENTS SUPPORTED : Random Number Generator
- --| :
- --| LIMITATIONS : None
- --| :
- --| AUTHOR(S) : Richard Conn (RLC) from Bill Whitaker's work
- --| CHANGE LOG : 09/30/88 RLC Design, code, test from
- --| : Bill Whitaker's original work
- --| : 10/11/88 RLC Modified based on ideas from
- --| : Ron Bell and his RAN2 Package
- --| :
- --| REMARKS : None
- --| :
- --| PORTABILITY ISSUES : Uses 16-bit integers, so should be quite
- --| : portable
- --| END PROLOGUE
- --------------------------------------------------------------------------
-
- function NUMBER return FLOAT;
- -- Return a floating point pseudo-random number
-
- end RANDOM;
- --
-
- with CALENDAR;
- package body RANDOM is
-
- X : INTEGER;
- Y : INTEGER;
- Z : INTEGER;
-
- --=============================================================
- function CONVERT_TO_FLOAT(ITEM : in INTEGER) return FLOAT is
- -- This function is necessary for some optimizing compilers
- -- in order to prevent expressions like FLOAT(INTEGER(FLOAT))
- -- from being optimized away
- begin
- return FLOAT(ITEM);
- end CONVERT_TO_FLOAT;
-
- --=============================================================
- procedure SEED is
- -- Generate seed values for X, Y, and Z using Package CALENDAR
- DAY_MONTH : FLOAT;
- SECONDS : FLOAT;
- HUNDREDS : FLOAT;
-
- begin
- SECONDS := FLOAT(CALENDAR.SECONDS(CALENDAR.CLOCK));
- HUNDREDS := (SECONDS/2.88) -
- CONVERT_TO_FLOAT(INTEGER((SECONDS/2.88) - 0.5));
- DAY_MONTH := FLOAT(CALENDAR.DAY(CALENDAR.CLOCK) *
- CALENDAR.MONTH(CALENDAR.CLOCK));
- X := INTEGER(SECONDS/2.88);
- begin
- Y := INTEGER(HUNDREDS * 30000.0);
- exception
- when others =>
- Y := INTEGER'LAST;
- end;
- begin
- Z := INTEGER(DAY_MONTH/372.0 * SECONDS * 30000.0);
- exception
- when others =>
- Z := INTEGER'LAST;
- end;
- end SEED;
-
- --
-
- -- Package body RANDOM
-
- --=============================================================
- function NUMBER return FLOAT is
- -- This rectangular random number routine is adapted from a report
- -- "A Pseudo-Random Number Generator" by B. A. Wichmann and I. D. Hill
- -- NPL Report DNACS XX (to be published)
- -- In this version, it is suitable for machines supporting
- -- INTEGER at only 16 bits and is portable in Ada
-
- W : FLOAT;
-
- begin
- X := 171 * (X mod 177) - 2 * (X / 177);
- -- Used to be: X := 171 * (X mod 177 - 177) - 2 * (X / 177);
- if X < 0 then
- X := X + 30269;
- end if;
- Y := 172 * (Y mod 176) - 35 * (Y / 176);
- if Y < 0 then
- Y := Y + 30307;
- end if;
- Z := 170 * (Z mod 178) - 63 * (Z / 178);
- if Z < 0 then
- Z := Z + 30323;
- end if;
-
- W := FLOAT(X) / 30269.0 + FLOAT(Y) / 30307.0 + FLOAT(Z) / 30323.0;
- return W - CONVERT_TO_FLOAT(INTEGER(W - 0.5));
- end NUMBER;
-
- --=============================================================
- begin
-
- SEED; -- Initialize random number generator
-
- end RANDOM;
-