## Park-Miller Pseudo-Random Number Generator

The Park-Miller PRNG, or MINSTD, is a linear congruential generator (LCG). The following FORTRAN 77 implementation has been adapted by Dick Valent and Fred Clare from the original Pascal version.

Save the code in minstd.f locally.

``````      REAL FUNCTION RAND()
C
C     THIS FUNCTION RETURNS A PSEUDO-RANDOM NUMBER FOR EACH INVOCATION.
C     IT IS A FORTRAN 77 ADAPTATION OF THE "INTEGER VERSION 2" MINIMAL
C     STANDARD NUMBER GENERATOR WHOSE PASCAL CODE APPEARS IN THE
C     ARTICLE:
C
C         PARK, STEVEN K. AND MILLER, KEITH W., "RANDOM NUMBER
C         GENERATORS: GOOD ONES ARE HARD TO FIND", COMMUNICATIONS OF
C         THE ACM, OCTOBER, 1988.
C
C     FORTRAN 77 IMPLEMENTATION BY DICK VALENT AND FRED CLARE.
C
INTEGER MPLIER, MODLUS, MOBYMP, MOMDMP
PARAMETER (MPLIER=16807, MODLUS=2147483647, MOBYMP=127773,
&           MOMDMP=2836)
COMMON  /SEED/ JSEED, IFRST
INTEGER HVLUE, LVLUE, TESTV, NEXTN
SAVE    NEXTN

IF (IFRST .EQ. 0) THEN
NEXTN = JSEED
IFRST = 1
END IF

HVLUE = NEXTN / MOBYMP
LVLUE = MOD(NEXTN, MOBYMP)
TESTV = MPLIER * LVLUE - MOMDMP * HVLUE

IF (TESTV .GT. 0) THEN
NEXTN = TESTV
ELSE
NEXTN = TESTV + MODLUS
END IF

RAND = REAL(NEXTN) / REAL(MODLUS)
END
C     ******************************************************************
SUBROUTINE SRAND(ISEED)
C
C     THIS SUBROUTINE SETS THE INTEGER SEED TO BE USED WITH THE
C     COMPANION RAND FUNCTION TO THE VALUE OF ISEED. A FLAG IS SET TO
C     INDICATE THAT THE SEQUENCE OF PSEUDO-RANDOM NUMBERS FOR THE
C     SPECIFIED SEED SHOULD START FROM THE BEGINNING.
C
INTEGER ISEED
COMMON /SEED/ JSEED, IFRST
JSEED = ISEED
IFRST = 0
END``````

The test program reads the seed from user input, initialises the PRNG, and prints 120 random numbers. Save the source as `test.f`:

``````C     ******************************************************************
C
C     TEST PROGRAM FOR PARK-MILLER MINIMUM STANDARD PRNG.
C
C     ******************************************************************
PROGRAM TEST
EXTERNAL SRAND
REAL     RAND
INTEGER  ISEED, I, J

PRINT *, 'MINIMUM STANDARD PSEUDO-RANDOM NUMBER GENERATOR'
C
C     SEED THE PRNG.
C
PRINT *, 'ENTER POSITIVE INTEGER SEED:'
CALL SRAND(ISEED)
C
C     PRINT 120 RANDOM NUMBERS.
C
DO 10 I = 1, 20
PRINT 200, (RAND(), J = 1, 6)
10 CONTINUE
200 FORMAT (6(X,F8.6))
END``````

To compile the program with `f2c` and `cc`, run:

``````\$ f2c test.f minstd.f
test.f:
MAIN main:
minstd.f:
rand:
srand:
\$ cc -I/usr/local/include -L/usr/local/lib -o test test.c minstd.c -lf2c -lm``````

Execute the binary `test` and enter a seed value:

``````\$ ./test
MINIMUM STANDARD PSEUDO-RANDOM NUMBER GENERATOR
ENTER POSITIVE INTEGER SEED:
12345
.096617  .833995  .947703  .035879  .011546  .051155
.765787  .584930  .914130  .783800  .333147  .195113
.267198  .792704  .983885  .148887  .339146  .034109
.266209  .167422  .864355  .209134  .916656  .238527
.930263  .935759  .306576  .629590  .512060  .197888
.910652  .334800  .982207  .949422  .930865  .051522
.923121  .887449  .356524  .105890  .695043  .583283
.242648  .177783  .996805  .307225  .530595  .709502
.604540  .498803  .378033  .598639  .325384  .724944
.126170  .531389  .057093  .566858  .174015  .666624
.942425  .335136  .624291  .461659  .096873  .142176
.553942  .097587  .149666  .432333  .229085  .234817
.574825  .076321  .731575  .583709  .397530  .286779
.893567  .175130  .404572  .635562  .886772  .980693
.510842  .713494  .691629  .211121  .307516  .423978
.790774  .543005  .283237  .363854  .297176  .642360
.137112  .448844  .721726  .046529  .017578  .439914
.636726  .455505  .673117  .078640  .698700  .048598
.783289  .737070  .928582  .672776  .337607  .154207
.764502  .979016  .330066  .417451  .094551  .124548``````