1      INTEGER FUNCTION ignuin(low,high)
2C**********************************************************************
3C
4C     INTEGER FUNCTION IGNUIN( LOW, HIGH )
5C
6C               GeNerate Uniform INteger
7C
8C
9C                              Function
10C
11C
12C     Generates an integer uniformly distributed between LOW and HIGH.
13C
14C
15C                              Arguments
16C
17C
18C     LOW --> Low bound (inclusive) on integer value to be generated
19C                         INTEGER LOW
20C
21C     HIGH --> High bound (inclusive) on integer value to be generated
22C                         INTEGER HIGH
23C
24C
25C                              Note
26C
27C
28C     If (HIGH-LOW) > 2,147,483,561 prints error message on * unit and
29C     stops the program.
30C
31C**********************************************************************
32
33C     IGNLGI generates integers between 1 and 2147483562
34C     MAXNUM is 1 less than maximum generable value
35C     .. Parameters ..
36      INTEGER maxnum
37      PARAMETER (maxnum=2147483561)
38      CHARACTER*(*) err1,err2
39      PARAMETER (err1='LOW > HIGH in IGNUIN',
40     +          err2=' ( HIGH - LOW ) > 2,147,483,561 in IGNUIN')
41C     ..
42C     .. Scalar Arguments ..
43      INTEGER high,low
44C     ..
45C     .. Local Scalars ..
46      INTEGER err,ign,maxnow,range,ranp1
47C     ..
48C     .. External Functions ..
49      INTEGER ignlgi
50      EXTERNAL ignlgi
51C     ..
52C     .. Intrinsic Functions ..
53      INTRINSIC mod
54C     ..
55C     .. Executable Statements ..
56      IF (.NOT. (low.GT.high)) GO TO 10
57      err = 1
58C      ABORT-PROGRAM
59      GO TO 80
60
61   10 range = high - low
62      IF (.NOT. (range.GT.maxnum)) GO TO 20
63      err = 2
64C      ABORT-PROGRAM
65      GO TO 80
66
67   20 IF (.NOT. (low.EQ.high)) GO TO 30
68      ignuin = low
69      RETURN
70
71C     Number to be generated should be in range 0..RANGE
72C     Set MAXNOW so that the number of integers in 0..MAXNOW is an
73C     integral multiple of the number in 0..RANGE
74
75   30 ranp1 = range + 1
76      maxnow = (maxnum/ranp1)*ranp1
77   40 ign = ignlgi() - 1
78      IF (.NOT. (ign.LE.maxnow)) GO TO 40
79      ignuin = low + mod(ign,ranp1)
80      RETURN
81
82   80 IF (.NOT. (err.EQ.1)) GO TO 90
83      WRITE (*,*) err1
84      GO TO 100
85
86C     TO ABORT-PROGRAM
87   90 WRITE (*,*) err2
88  100 WRITE (*,*) ' LOW: ',low,' HIGH: ',high
89      WRITE (*,*) ' Abort on Fatal ERROR'
90      IF (.NOT. (err.EQ.1)) GO TO 110
91      STOP 'LOW > HIGH in IGNUIN'
92
93  110 STOP ' ( HIGH - LOW ) > 2,147,483,561 in IGNUIN'
94
95  120 END
96