Looking for some random-functions ..._(re)

Sun, 21 Sep 1997 17:50:53 +0200



Achim Kalwa wrote:

> You can use the following external function declaration:
>
> FUNCTION Rand : Integer; C;
>
> and do the following example:
>
> FOR i := 1 TO 10 DO WriteLn(Rand);
>
> Alternatively, there is a random number generator unit called "Rand" written by
> Frank Heckenbach (heckenb@mi.uni-erlangen.de).
>
> To Frank: Would you post your unit again, please? Im interested, too.

The unit follows below. I did some minor changes since last time.

But please note:

- The changes might rely on some bug fixes in GPC that were done after the
  last beta release, so the unit might not work with the currently available
  version. But that'll not be a big problem, since the next beta will be
  available real soon now, and the unit should work with it then... :-)

- See the notes at the beginning of the unit.

--
Frank Heckenbach, Erlangen, Germany
heckenb@mi.uni-erlangen.de
http://home.pages.de/~fjf/links.htm

File Rand.Pas:

{ Random unit for GPC for BP compatibility
  This package is released as part of the GNU Pascal project.

  IMPORTANT NOTES:

  - This unit is only intended for BP compatibility. While it should be
    portable (if not, please report), it's *not* meant to be GPC's default
    random generator. Especially, the range for integer randoms is only
    16 bits, as in BP. OTOH, it provides the RandSeed variable, and if it's
    set to the same value, it produces the exact same sequence of random
    numbers as BP's random generator does (whoever might need this... ;-)

    If you don't care for such kind of compatibility, you might prefer to
    use the Rand/SRand C functions. (BTW: This unit uses them to initialize
    RandSeed on non-Dos systems, you can take that as an example on how to
    use them.)

  - Since function overloading doesn't work yet, you have to use "RandReal"
    instead of "Random" for real numbers.

  This library is a free library; you can redistribute and/or modify
  it under the terms of the GNU Library General Public License,
  version 2, as published by the Free Software Foundation.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library (see the file COPYING.LIB);
  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  Cambridge, MA 02139, USA.

  v1.0, September 1997, Frank Heckenbach, heckenb@mi.uni-erlangen.de }

UNIT Rand;
INTERFACE

TYPE
  Card8 =Cardinal(8);
  Card16=Cardinal(16);
  Card32=Cardinal(32);
  Card64=Cardinal(64);
  Int32 =Integer(32);

VAR RandSeed:Int32 VALUE 0;

FUNCTION Random(Range:Card16):Card16;
FUNCTION RandReal:Real;
PROCEDURE Randomize;

IMPLEMENTATION

{### LOCAL $R-}{$W-,R-,W+}
PROCEDURE NextRand;
BEGIN
  RandSeed:=$8088405*RandSeed+1
END;
{### END LOCAL $R}

FUNCTION Random(Range:Card16):Card16;
BEGIN
  NextRand;
  Random:=(Card64(RandSeed)*Range) DIV $100000000
END;

FUNCTION RandReal:Real;
BEGIN
  NextRand;
  RandReal:=RandSeed/$100000000+0.5
END;

{$IFDEF __DJGPP__}{$DEFINE DOS}{$ENDIF}
{$IFDEF __EMX__}{$DEFINE DOS}{$ENDIF}

{$IFDEF DOS}
TYPE
  PDPMIRegs=^TDPMIRegs;
  TDPMIRegs=RECORD
    CASE (d,x,h) OF
      d:(edi,esi,ebp,res,ebx,edx,ecx,eax:Card32);
      x:(di,di_hi,si,si_hi,bp,bp_hi,res_lo,res_hi,bx,bx_hi,dx,dx_hi,
         cx,cx_hi,ax,ax_hi,flags,es,ds,fs,gs,ip,cs,sp,ss:Card16);
      h:(edi_b,esi_b,ebp_b,res_b:ARRAY[0..3] OF Card8;
         bl,bh,ebx_b2,ebx_b3,
         dl,dh,edx_b2,edx_b3,
         cl,ch,ecx_b2,ecx_b3,
         al,ah,eax_b2,eax_b3:Card8)
    END;

{$W-}
FUNCTION __DPMI_Simulate_Real_Mode_Interrupt(Vector:Integer;VAR Regs:TDPMIRegs):Integer; C;
{$W+}

PROCEDURE Randomize;
TYPE Card32LoHi=RECORD Lo,Hi:Card16 END;
VAR DPMIRegs:TDPMIRegs;
BEGIN
  DPMIRegs.ah:=$2C;
  {$X+}
  __DPMI_Simulate_Real_Mode_Interrupt($21,DPMIRegs);
  {$X-}
  WITH Card32LoHi(RandSeed) DO
    BEGIN
      Lo:=DPMIRegs.cx;
      Hi:=DPMIRegs.dx
    END
END;

{$ELSE}
FUNCTION Rand:Integer; C;
PROCEDURE SRand(Seed:Cardinal); C;
FUNCTION GetPID:Integer; C;

PROCEDURE Randomize;
BEGIN
  SRand(GetPID);
  RandSeed:=Rand
END;
{$ENDIF}
END.


Frank Heckenbach (heckenb@mi.uni-erlangen.de)

HTML conversion by Lluís de Yzaguirre i Maura
Institut de Lingüística Aplicada - Universitat "Pompeu Fabra"
e-mail: de_yza@upf.es