[comp.sys.atari.st] Random Number Generator for OSS PP

csrobe@ICASE.EDU (Charles S. [Chip] Roberson) (03/17/89)

Here are 2 code fragments for an excellent Random Number generator written
by Dr. Steve Park of William and Mary.  For more information, see 
"Random Number Generators:  Good Ones are Hard to Find", in the October
1988 issue of _Communications_of_The_ACM_.

    s    : integer;                            { stream index }
    seed : array [0..255] of real;

{* This file should be used on systems that only have 16-bit integers *}

  function Random : real;
  const
    a = 16807.0;
    m = 2147483647.0;
    q = 127773.0;       { m div a }
    r = 2836.0;         { m mod a }
  var
    lo, hi, test : real;
  begin
    if (s > 0) then
      begin
        hi   := trunc(seed[s] / q);
        lo   := seed[s] - q * hi;
        test := a * lo - r * hi;
        if test > 0.0 then
          seed[s] := test
        else
          seed[s] := test + m;
        Random  := seed[s] / m
      end
    else
      Random := 0.5
  end;  { Random }


  procedure Plant_Seeds;                    { a private procedure which is  }
  const                                     { used to "plant" a sequence of }
    a = 8350.0;                             { seeds seperated one from the  }
    m = 2147483647.0;                       { next by 8,016,548 steps       }
    q = 257183.0;       { m div a }
    r = 5597.0;         { m mod a }
  var
    j            : integer;
    lo, hi, test : real;
  begin
    for j := 2 to 255 do
      begin
        hi   := trunc(seed[j - 1] / q);
        lo   := seed[j - 1] - q * hi;
        test := a * lo - r * hi;
        if test > 0.0 then
          seed[j] := test
        else
          seed[j] := test + m
      end
  end;  { Plant_Seeds }

{*}

  procedure Randomize;
  var
    t : integer;                            { 32-bit 2's compliment integer }
  begin
    repeat
      writeln;
      write('Enter a positive integer seed (9 digits or less) >> ');
      readln(t)
    until (0 < t) and (t < 2147483647);
    writeln;
    seed[1] := t;                           { this is seed[1] - now }
    Plant_Seeds                             { plant the other seeds }
  end;  { Randomize }


  procedure Select_Stream(stream : integer);
  begin
    s := stream
  end;  { Select_Stream }

{ end implementation }

procedure init_rngs;
begin  { initialize }

  s       := 1;                             { supply a default stream }
  seed[s] := 123456789.0;                   { and an initial seed     }
  Plant_Seeds

end; { end initialize }

--------------------------------------------------------------------------
    s    : integer;                            { stream index }
    seed : array [0..255] of integer;

{* This file should be used on systems that has 32-bit integers or larger *}

  function Random : real;
  const
    a = 16807;
    m = 2147483647;
    q = 127773;       { m div a }
    r = 2836;         { m mod a }
  var
    lo, hi, test : integer;
  begin
    if (s > 0) then
      begin
        hi   := trunc(seed[s] / q);
        lo   := seed[s] - q * hi;
        test := a * lo - r * hi;
        if test > 0.0 then
          seed[s] := test
        else
          seed[s] := test + m;
        Random  := seed[s] / m
      end
    else
      Random := 0.5
  end;  { Random }


  procedure Plant_Seeds;                    { a private procedure which is  }
  const                                     { used to "plant" a sequence of }
    a = 8350;                               { seeds seperated one from the  }
    m = 2147483647;                         { next by 8,016,548 steps       }
    q = 257183;       { m div a }
    r = 5597;         { m mod a }
  var
    j            : integer;
    lo, hi, test : integer;
  begin
    for j := 2 to 255 do
      begin
        hi   := trunc(seed[j - 1] / q);
        lo   := seed[j - 1] - q * hi;
        test := a * lo - r * hi;
        if test > 0.0 then
          seed[j] := test
        else
          seed[j] := test + m
      end
  end;  { Plant_Seeds }

{*}

  procedure Randomize;
  var
    t : integer;                            { 32-bit 2's compliment integer }
  begin
    repeat
      writeln;
      write('Enter a positive integer seed (9 digits or less) >> ');
      readln(t)
    until (0 < t) and (t < 2147483647);
    writeln;
    seed[1] := t;                           { this is seed[1] - now }
    Plant_Seeds                             { plant the other seeds }
  end;  { Randomize }


  procedure Select_Stream(stream : integer);
  begin
    s := stream
  end;  { Select_Stream }

{ end implementation }

procedure init_rngs;
begin  { initialize }

  s       := 1;                             { supply a default stream }
  seed[s] := 123456789;                     { and an initial seed     }
  Plant_Seeds

end; { end initialize }

--------------------------------------------------------------------------
I know that this generator works under OSS Personal Pascal, because I've
used it.  

Enjoy,
-c
|Chip Roberson                ARPANET:  csrobe@cs.wm.edu                  |
|Dept of Comp. Sci.                     csrobe@icase.edu                  |
|College of William and Mary  BITNET:   #csrobe@wmmvs.bitnet              |
|Williamsburg, VA 23185       UUCP:     ...!uunet!pyrdc!gmu90x!wmcs!csrobe|

     "It takes 40 dumb animals to make a fur coat,
         and just one dumb animal to wear it."      -European TV commercial

[A Cruelty-Free Companies list is available for anonymous ftp from cs.wm.edu.]