Random Number Generator
mark
mark at hp-pcd.UUCP
Wed Jul 31 03:56:00 AEST 1985
;; Strip off all lines that begin with ;;
;; The following routine is pretty good if you only need a 64K period.
;; Just ensure that there are no label conflicts and you can merge it into
;; your program (MASM 1.25) or if you want to assemble a stand-alone object
;; you will have to add the appropriate header and tail.
;; Note that the seeder routine (SRAND) makes a INT 21 call to get the clock
;; value from MS-DOS. This will have to be deleted (or modified) it not
;; running under MS-DOS.
;; Enjoy. Mark Rowe, Corvallis, Or. hp-pcd!mark
RandC equ 13849 ; Linear congruential offset
RandF equ 23392 ; Skip value for result of 64K
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Random number generator (and seeder) (04/17/85)
; The Rand routine generates a random number from the previous random
; number via the linear congruential method. The formula is as follows:
; X(n+1) = (55994*X(n) + 13849) mod 65537
; The value is returned in AX as a 16 bit unsigned integer from 0 to 65535.
; The result of 65536 is trapped and skipped over (since 65536 is too big to
; store in 16 bits). The period is 64K. The initial seed is zero if not
; altered via a call to Srand. The AX and DX registers are altered.
; The Srand routine sets the seed for the random number generator (Rand).
; If the value of AX is nonzero then it becomes the random number seed and
; no registers are altered. If AX is zero then the seed is generated from
; the current clock value and the AX, BX, CX and DX registers are altered.
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Rand:
mov AX,CS:[RandX] ; Set DX:AX to previous random number
xor DX,DX
or AX,AX ; Skip multiply code if zero
jz Rand1
mul CS:[RandA] ; Compute product mod 65537 (in DL:AX)
sub AX,DX
mov DL,0
adc AX,0
jnz Rand1
inc DL
Rand1: add AX,RandC ; Compute sum (in DL:AX)
adc DL,0
jz Rand2 ; Jif sum < 64K
dec AX ; AX=sum mod 65537
jns Rand2 ; Jif result not 64K
mov AX,RandF ; AX=value following 64K
Rand2: mov CS:[RandX],AX ; Store new random number
ret ; Return with AX=new random number
Srand:
or AX,AX ; Test parameter (AX)
jnz Srand1 ; Jif parameter is nonzero
mov AH,2CH ; Get current time
int 21H
mov AL,CH ; Convert time to seconds/100)
mul byte ptr CS:Sixty
mov CH,0
add AX,CX
mov CX,DX
mul word ptr CS:Sixty
mov DL,CH
add AX,DX
mul word ptr CS:Hundred
mov CH,0
add AX,CX
Srand1: mov CS:[RandX],AX ; Set random number seed to AX
ret
Sixty dw 60 ; Constant multiplier
Hundred dw 100 ; Constant multiplier
RandA dw 55994 ; Linear congruential multiplier
RandX dw 0 ; Random number (initially zero)
More information about the Comp.sources.unix
mailing list