Overview
-Several pseudo random number generators are listed on this web page:
-"RNG1" "RNG2" "RNG3" work on every HP-41.
-"RNG4" & the M-Code routine RAND require a Time-Module.
-Finally, the last program is an attempt to play ( win? ) the lottery...
Program#1
-A well known RNG is given by the formula: xn+1 = FRC
( 9821 xn + 0.211327 ) which provides 1 million random
numbers.
-The following program gives 1,000,000,000 random numbers r
( 0 <= r < 1 ). The formula xn+1 = FRC ( 98
xn + 0.236067977 ) is used.
-The coefficient 98 = 43,046,721 may be replaced by
a where a = 1 ( mod 20 )
and 0.236067977 may be replaced by b where
b*109 is not divisible by 2 or 5.
01 LBL "RNG1"
02 9 03 ENTER^ 04 ENTER^ 05 R^ 06 * |
07 FRC
08 * 09 FRC 10 * 11 FRC 12 * |
13 FRC
14 * 15 FRC 16 * 17 FRC 18 * |
19 FRC
20 * 21 FRC 22 5 23 SQRT 24 + |
25 FRC
26 END |
( 35 bytes / SIZE 001 )
STACK | INPUTS | OUTPUTS |
X | xn | xn+1 |
Example:
0.2 XEQ "RNG1" yields 0.436067977
R/S 0.779021394 ... etc ...
Program#2
-"RNG2" provides 9,999,999,996 random numbers with the formula:
xn+1 = ( 1059 xn ) MOD p where
p = 9,999,999,967 is the greatest prime < 1010
xn are integers between 0 and p ( exclusive
) which are then divided by p to be reduced to a number between 0 and 1.
-This routine works well because the MOD function gives exact results
even when the operands are greater than 1010.
-Actually, the exponent 59 may be replaced by any integer m provided
m is relatively prime to p-1 = 2*3*11*457*331543
but I don't know what is the best choice.
-Unlike "RNG1" and other routines based upon the same type of formulae,
the least significant digits don't go through any cycle of ten, one hundred
and so on.
-Register R00 is used to store the different xn integers.
01 LBL "RNG2"
02 RCL 00 03 E59 04 * 05 10 06 10^X 07 33 08 - 09 MOD 10 STO 00 11 LASTX 12 / 13 END |
( 26 bytes / SIZE 001 )
STACK | INPUTS | OUTPUTS |
X | / | 0 < r < 1 |
Example:
1 STO 00
XEQ "RNG2" gives 0.3129146797
( and R00 = 3129146787 = 1059 ( mod p ) )
R/S
0.6904570204 ( R00 = 6904570181 ) ... etc ...
-Actually if p is a prime, ( Z/pZ-{0} ; * ) is a
group
and if a is an integer, the number of distinct elements
in the subset { 1 ; a ; a2 ; ....... ; ak
; .... } ( mod p ) divides p-1
-If p-1 is the smallest positive integer q such that aq
= 1 ( mod p ) , then the sequence a ; a2 ; .......
; ak ; .... ; ap-1 ( mod p )
is a permutation of 1 ; 2 ; ...... ; p-1
-In particular, if p = 2p' + 1 where p' is also a prime,
and if ap' is not equal to 1 ( mod p ) then a
satisfies the required property.
-For instance, p = 7,841,296,787 = 2*3,920,648,393 + 1
7,841,296,787 and 3,920,648,393 are primes and -1024 =
4,851,307,369 ( mod p )
satisfies (-1024)p' = -1 therefore
the routine:
E24
*
CHS
7841296787
MOD
gives 7,841,296,786 random integers
-These ideas may be used to create your own RNG.
Program#3
-The following algorithm is given by Clifford Pickover in "Keys to Infinity"
( John Wiley & Sons ) ISBN 0-471-11857-5
01 LBL "RNG3"
02 LN 03 E2 04 * 05 1 06 MOD 07 END |
( 17 bytes / SIZE 001 )
STACK | INPUTS | OUTPUTS |
X | xn | xn+1 |
Example:
0.1 XEQ "RNG3" produces
0.74149070
R/S
0.09073404 ... etc ...
Program#4
01 LBL "RNG4"
02 DATE 03 TIME 04 + 05 E49 06 * 07 PI 08 MOD 09 LN1+X 10 R-D 11 FRC 12 END |
( 25 bytes / SIZE 000 )
STACK | INPUTS | OUTPUTS |
X | / | 0 < r < 1 |
-I cannot give any example since the result depends on the instant
you press R/S
M-Code Routine
-This M-Code routine uses the TIME module - or an HP41-CX
084 "D"
00E "N"
001 "A"
012 "R"
130 LDI S&X
010 16d
270 RAMSLCT
130 LDI S&X
0FB 251d
3F0 PRPH SLCT
3E8 WRIT 15(e)
038 READDATA
1BC RCR 11
046 C=0 S&X
270 RAMSLCT
05E C=0 MS
130 LDI S&X
041 65d
2A0 SETDEC
10E A=C ALL
04E C=0 ALL
35C PT=12
1D0 LD@PT- 7
210 LD@PT- 8
110 LD@PT- 4
050 LD@PT- 1
090 LD@PT- 2
250 LD@PT- 9
190 LD@PT- 6
1D0 LD@PT- 7
210 LD@PT- 8
1D0 LD@PT- 7
044 CLRF 4
070 N=C ALL
171 ?NCXQ
064 195C
10E A=C ALL
0B0 C=N ALL
261 ?NCXQ
060 1898
0E8 WRIT 3(X)
3E0 RTN
( 42 words / SIZE 000 )
-"RAND" uses no data register
-XEQ "RAND" returns a pseudo-random number ( between 0 and 1 ) in X-register
-The previous content of register X is overwritten.
-Execution time = 0.22 second
Winning the Lottery?
-If you need, for instance, 7 integers between 1 and 49 , you can use
7 random numbers between 0 and 1,
multiply them by 49 , add 1 and take the integer part of the
result.
-The small routine hereafter is another possibility, if you accept
to calculate the integer part in your mind:
01 LBL "$$$"
02 R-D 03 49 04 MOD 05 1 06 + 07 END |
( 16 bytes / SIZE 000 )
STACK | INPUTS | OUTPUTS |
X | r | 0 < N < 50 |
Example:
41 XEQ "$$$" yields 47.1270
R/S
6.1759
R/S
11.8535
R/S
43.1567
R/S
23.6963
R/S
35.6962
R/S
37.2418 suggesting
47-06-11-43-23-35-37
Notes:
1-I'm not a statistician and I can't assure all these RNGs would stand
up to sophisticated tests, but one may use his imagination in devising
variations.
2-If you win one million dollars thanks to one of these programs, I
accept to share the jackpot...