Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: notesfiles - hp 1.2 08/01/83; site hp-pcd.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!oliveb!hplabs!hp-pcd!mark From: mark@hp-pcd.UUCP (mark) Newsgroups: net.sources Subject: Re: Random Number Generator Message-ID: <20300002@hpcvlo.UUCP> Date: Tue, 30-Jul-85 13:56:00 EDT Article-I.D.: hpcvlo.20300002 Posted: Tue Jul 30 13:56:00 1985 Date-Received: Sun, 4-Aug-85 08:12:47 EDT References: <-149000@faust.UUCP> Organization: Hewlett-Packard - Corvallis, OR Lines: 68 Nf-ID: #R:faust:14900002:hpcvlo:20300002:000:2713 Nf-From: hpcvlo!mark Jul 30 09:56:00 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)