Greetings,
I'm afraid there are some inaccuracies in Michael's posting.
First, the RANDOM function in COBOL II/iX does not use the "clock
milliseconds" as the seed, or in any other way. You either specify the
seed value yourself, or let it default. In COBOL II/iX, the default
seed value is zero.
The suggestion to use the return value from RANDOM to re-seed it is
essentially what COBOL II/iX does for you automatically.
The statement that you don't have control of the seed value is
incorrect. You have the option of specifying an argument to RANDOM,
which seeds it (or re-seeds it); or not specifying an argument, which
causes it to return the next pseudo-random number in the sequence
determined by the previous seed. If you never specify a seed, it's the
same as specifying an initial seed value of zero.
The techniques Michael describes using RAND and RAND1, if I am
understanding him correctly, are quite possible using the standard
RANDOM function in COBOL.
The implication that you will get the same result if you call RANDOM
twice within a millisecond is incorrect. As I said, the RANDOM function
doesn't use any system timer value.
If I want a reasonably unpredictable sequence of pseudo-random numbers,
I will typically use a seed value derived from the return value from a
call to FUNCTION CURRENT-DATE. This is what I do, for example, in a
routine I wrote to generate a random strong password.
Bottom line: Save yourself some trouble and use the RANDOM function
provided by the COBOL language. It's standard, portable COBOL.
Walter
Walter J. Murray
-----Original Message-----
From: HP-3000 Systems Discussion [mailto:[log in to unmask]] On
Behalf Of Michael Anderson
Sent: Wednesday, September 15, 2010 4:53 PM
To: [log in to unmask]
Subject: Re: [HP3000-L] RANDOM NUMBER..
Such library functions will repeat patterns using the clock milliseconds
as the initial seed. This "ramdom" function may provide enough
randomness
for some, but not all.
To achieve more randomness with the standard system clock algorithm
you'll
need to set the initial seed value first. Then use that seed value to
generate your first random number, then push the first random number
back
into the seed, thus making the seed more random than just using the
clock.
Then generate another random number using the random seed.
Correct me if I'm wrong. To the best of my knowledge, when using the
single function, you do not have control of the seed value. So when a
pattern begins to repeat you're just SOL.
My point is: On MPE there are two intrinsic functions available to give
you more control of your random number generator. They are RAND1 and
RAND.
You can use these two routines in various different ways to generate a
random seed, which is then passed to RAND to generate the random number.
Not only can you use the random number as a seed for the next random
number, but to break any pattern you can use any three digits of the
random number to pause for a random number of milliseconds, then get a
new
seed value from the system clock by calling RAND1, then continue in the
loop. None of this is possible using the standard "random" function.
Example:
RAND1 returns the seed to be passed to the RAND intrinsic. RAND1 is
based
on the system timer (clock milliseconds). The random function works the
same way, therefore you will in up with the same random number if call
it
twice within 1 millisecond. Worse, if you are generating many random
numbers you will start to see a pattern.
About 20 years ago I was asked to write a random employee list, using
COBOL74 on 16 bit MPE V. I would initially call RAND1 to get the first
seed. From that point on I used the result from RAND as the next seed,
and
so on.
To test this routine and make sure it will work for a truly random
subset
of employees, I wrote a little program to gen lotto numbers, and here it
is:
====================================
IDENTIFICATION DIVISION.
PROGRAM-ID. RANNUM.
AUTHOR. MICHAEL ANDERSON.
****************************************************************
* - RANNUM - is a program developed to test and display the *
* unbiased selection of numbers, that the HP random *
* number generator will produce. *
* The original need for this was the random employee*
* list. *
****************************************************************
DATE-COMPILED.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. HP3000.
OBJECT-COMPUTER. HP3000.
SPECIAL-NAMES.
CONDITION-CODE IS CC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 RANDOM-SEED PIC S9(9) COMP VALUE 0.
01 RANDOM-RETURN PIC S9(9) COMP VALUE 0.
01 DISP-N PIC 9(9) VALUE ZERO.
01 FILLER REDEFINES DISP-N.
02 FILLER PIC 9.
02 FILLER PIC 99.
02 FILLER PIC 99.
02 FILLER PIC 99.
02 RANDOM-PICK PIC 99.
01 DISP-N18 PIC ZZZ,ZZZ,ZZZ,ZZZ,ZZZ,ZZ9.
01 TBL-IDX PIC S9(4) COMP VALUE 0.
01 IDX PIC S9(4) COMP VALUE 0.
01 X PIC S9(18) COMP VALUE 0.
01 DOLLARS PIC S9(18) COMP VALUE 0.
01 SIXFLAGS PIC S9(4) COMP VALUE 0.
01 PLAYS PIC 99 VALUE 0.
01 F PIC S9(4) COMP VALUE 0.
01 T PIC S9(4) COMP VALUE 0.
01 NUMF PIC 99 VALUE 0.
01 NUMT PIC 99 VALUE 0.
01 FROM-NUM-TABLE.
02 FROM-NUMBERS.
03 FROM-NUM OCCURS 6 TIMES PIC 99.
01 TO-NUM-TABLE.
02 TO-NUMBERS.
03 TO-NUM OCCURS 6 TIMES PIC 99.
01 NUMBER-TABLE.
02 RANDOM-NUMBERS.
03 RANDOM-NUMBER OCCURS 6 TIMES PIC 99.
PROCEDURE DIVISION.
0000-RANNUM.
DISPLAY "RANDOM NUMBERS.".
DISPLAY "--------------------".
MOVE ZERO TO PLAYS SIXFLAGS DOLLARS.
PERFORM PLAY-LIST UNTIL DOLLARS > 10.
GOBACK.
PLAY-LIST.
INITIALIZE RANDOM-NUMBERS.
MOVE ZERO TO TBL-IDX.
CALL INTRINSIC "RAND1" GIVING RANDOM-SEED.
*
* GET NUMBERS
PERFORM VARYING X FROM 1 BY 1
UNTIL TBL-IDX IS EQUAL TO 6
IF DISP-N > 0
MOVE DISP-N TO RANDOM-SEED
END-IF
CALL INTRINSIC "RAND" USING RANDOM-SEED
GIVING RANDOM-RETURN
MOVE RANDOM-RETURN TO DISP-N
IF ( RANDOM-PICK > 0 AND < 55 ) AND
( RANDOM-PICK <> RANDOM-NUMBER(1) AND RANDOM-NUMBER(2)
AND RANDOM-NUMBER(3) AND RANDOM-NUMBER(4)
AND RANDOM-NUMBER(5) AND RANDOM-NUMBER(6) )
ADD 1 TO TBL-IDX
MOVE RANDOM-PICK TO RANDOM-NUMBER(TBL-IDX)
END-IF
END-PERFORM.
*
* SORT NUMBERS
IF RANDOM-NUMBERS <> TO-NUMBERS
ADD 1 TO DOLLARS
MOVE RANDOM-NUMBERS TO FROM-NUMBERS
INITIALIZE NUMF NUMT TO-NUMBERS X T F
PERFORM VARYING X FROM 1 BY 1 UNTIL X > 54
PERFORM VARYING F FROM 1 BY 1 UNTIL F > 6
MOVE FROM-NUM(F) TO NUMF
IF NUMF = X
ADD 1 TO T
MOVE FROM-NUM(F) TO TO-NUM(T)
END-IF
END-PERFORM
END-PERFORM
*
* DISPLAY NUMBERS
MOVE TO-NUMBERS TO RANDOM-NUMBERS
DISPLAY RANDOM-NUMBER(1)
", " RANDOM-NUMBER(2)
", " RANDOM-NUMBER(3)
", " RANDOM-NUMBER(4)
", " RANDOM-NUMBER(5)
", " RANDOM-NUMBER(6).
> The manual shows the format to be:
>
> 77 my-random pic v99999.
>
> Compute my-random = function random (30).
>
> My problem.. I keep getting a compile error on the word 'function'.
>
> 00604 011010 32 356 Q UNDEFINED DATA NAME FUNCTION.
>
> I'm on the latest and greatest and LAST version of the operating
system.
> C.75.00.
>
> I've tried taking the word 'function' out, along with various other
> things.
>
> From page 10-49/50 of the manual.
>
> Mr Kim Borgman
> IT mgr, RNDC of Indiana.
>
> * To join/leave the list, search archives, change list settings, *
> * etc., please visit http://raven.utc.edu/archives/hp3000-l.html *
>
* To join/leave the list, search archives, change list settings, *
* etc., please visit http://raven.utc.edu/archives/hp3000-l.html *
* To join/leave the list, search archives, change list settings, *
* etc., please visit http://raven.utc.edu/archives/hp3000-l.html *
|