home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / ada / bd3.arc / RANDOM.LST < prev    next >
File List  |  1989-03-12  |  4KB  |  102 lines

  1.   1 package RANDOM is
  2.   2 --------------------------------------------------------------------------
  3.   3 --| BEGIN PROLOGUE
  4.   4 --| DESCRIPTION            : Package RANDOM contains the function NUMBER
  5.   5 --|                        : which returns a pseudo-random number
  6.   6 --|                        : of type FLOAT in the range 0.0 .. 1.0.
  7.   7 --|                        : 
  8.   8 --| REQUIREMENTS SUPPORTED : Random Number Generator
  9.   9 --|                        : 
  10.  10 --| LIMITATIONS            : None
  11.  11 --|                        : 
  12.  12 --| AUTHOR(S)              : Richard Conn (RLC) from Bill Whitaker's work
  13.  13 --| CHANGE LOG             : 09/30/88  RLC  Design, code, test from
  14.  14 --|                        :                 Bill Whitaker's original work
  15.  15 --|                        : 10/11/88  RLC  Modified based on ideas from
  16.  16 --|                        :                 Ron Bell and his RAN2 Package
  17.  17 --|                        : 
  18.  18 --| REMARKS                : None
  19.  19 --|                        : 
  20.  20 --| PORTABILITY ISSUES     : Uses 16-bit integers, so should be quite
  21.  21 --|                        : portable
  22.  22 --| END PROLOGUE
  23.  23 --------------------------------------------------------------------------
  24.  24 
  25.  25     function NUMBER return FLOAT;
  26.  26     -- Return a floating point pseudo-random number
  27.  27 
  28.  28 end RANDOM;
  29.  29 --
  30.  30 with CALENDAR;
  31.  31 package body RANDOM is
  32.  32  
  33.  33     X : INTEGER;
  34.  34     Y : INTEGER;
  35.  35     Z : INTEGER;
  36.  36  
  37.  37     --=============================================================
  38.  38     function CONVERT_TO_FLOAT(ITEM : in INTEGER) return FLOAT is
  39.  39     -- This function is necessary for some optimizing compilers
  40.  40     -- in order to prevent expressions like FLOAT(INTEGER(FLOAT))
  41.  41     -- from being optimized away
  42.  42     begin
  43.  43         return FLOAT(ITEM);
  44.  44     end CONVERT_TO_FLOAT;
  45.  45  
  46.  46     --=============================================================
  47.  47     procedure SEED is
  48.  48     -- Generate seed values for X, Y, and Z using Package CALENDAR
  49.  49         DAY_MONTH : FLOAT;
  50.  50         SECONDS   : FLOAT;
  51.  51         HUNDREDS  : FLOAT;
  52.  52 
  53.  53     begin
  54.  54         SECONDS := FLOAT(CALENDAR.SECONDS(CALENDAR.CLOCK));
  55.  55         HUNDREDS := (SECONDS/2.88) -
  56.  56             CONVERT_TO_FLOAT(INTEGER((SECONDS/2.88) - 0.5));
  57.  57         DAY_MONTH := FLOAT(CALENDAR.DAY(CALENDAR.CLOCK) *
  58.  58             CALENDAR.MONTH(CALENDAR.CLOCK));
  59.  59         X := INTEGER(SECONDS/2.88);
  60.  60         Y := INTEGER(HUNDREDS * 30000.0);
  61.  61         Z := INTEGER(DAY_MONTH/372.0 * SECONDS * 30000.0);
  62.  62     end SEED;
  63.  63 
  64.  64 -- 
  65.  65 -- Package body RANDOM
  66.  66 
  67.  67     --=============================================================
  68.  68     function NUMBER return FLOAT is
  69.  69     --  This rectangular random number routine is adapted from a report
  70.  70     --  "A Pseudo-Random Number Generator" by B. A. Wichmann and I. D. Hill
  71.  71     --  NPL Report DNACS XX (to be published)
  72.  72     --  In this version, it is suitable for machines supporting
  73.  73     --  INTEGER at only 16 bits and is portable in Ada
  74.  74 
  75.  75         W : FLOAT;
  76.  76  
  77.  77     begin
  78.  78         X := 171 * (X mod 177) - 2 * (X / 177);
  79.  79         -- Used to be: X := 171 * (X mod 177 - 177) - 2 * (X / 177);
  80.  80         if X < 0 then
  81.  81             X := X + 30269;
  82.  82         end if;
  83.  83         Y := 172 * (Y mod 176) - 35 * (Y / 176);
  84.  84         if Y < 0 then
  85.  85             Y := Y + 30307;
  86.  86         end if;
  87.  87         Z := 170 * (Z mod 178) - 63 * (Z / 178);
  88.  88         if Z < 0 then
  89.  89             Z := Z + 30323;
  90.  90         end if;
  91.  91  
  92.  92         W := FLOAT(X) / 30269.0 + FLOAT(Y) / 30307.0 + FLOAT(Z) / 30323.0;
  93.  93         return W - CONVERT_TO_FLOAT(INTEGER(W - 0.5));
  94.  94     end NUMBER;
  95.  95 
  96.  96 --=============================================================
  97.  97 begin
  98.  98 
  99.  99     SEED; -- Initialize random number generator
  100. 100  
  101. 101 end RANDOM;
  102.