home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
ada
/
bd3.arc
/
RANDOM.ADA
< prev
next >
Wrap
Text File
|
1989-03-13
|
4KB
|
114 lines
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;