Post Reply 
HP41C random number generator help
12-06-2017, 03:03 AM
Post: #21
RE: HP41C random number generator help
This (rn = new seed = 9821 · previous seed + 0,211327 )-type-also-PPC-ROM-done-it-that-way here as MCode, for the connoisseurs
Code:
*  HP41 Random Number in MCode
*  ===========================
*
*  SEED - save X as seed for RN in buffer
*  RN   - get a random number f(seed)
*          it is saved in buffer as new seed
*          with no seed timer is used to get one
*  Note: OFF/ON and PACK will discard seed buffer
*  Limitation: HP41CX only
*  Author: MF, about 3 decades ago
*
B400 04E C=0    ALL   - look for SEED-buffer, must be on 256-boundary
B401 35C PT=    12
B402 250 LC     9     - buffer #9
B403 260 SETHEX
B404 3F0 PERSLCT
B405 130 LDI
B406 0C0 CON    192
B407 108 SF     8
B408 1AD *
B409 16A NCGO   5A6B =FNDEOB+2, find SEED buffer
B40A 084 D
B40B 005 E
B40C 005 E
B40D 013 S
B40E 0F8 C=REG  3/X             <= SEED, saves X as new seed
B40F 361 *
B410 050 NCXQ   14D8 =CHK_NO_S, check for character data
B411 158 M=C
B412 3E9 *
B413 08C NCXQ   23FA =GSB256, fast absolute GOSUB
B414 033 JNC    +06 B41A
B415 038 RDATA
B416 000 NOP
B417 2EE ?C#0   ALL       not empty?
B418 321 *
B419 0C3 CGO    30C8 ..., pack and say "try again"
B41A 2A0 SETDEC
B41B 198 C=M
B41C 106 A=C    X
B41D 130 LDI
B41E 003 CON    03
B41F 146 A=A+C  X
B420 03C RCR    3
B421 0A6 A<>C   X
B422 35C PT=    12
B423 250 LC     9     - buffer #9
B424 010 LC     0
B425 050 LC     1
B426 2F0 WDATA        - save buffer
B427 3E0 RTN
B428 08E N
B429 012 R            <= RN, get a random number
B42A 3E9 *
B42B 08C NCXQ   23FA =GSB256, fast absolute GOSUB
B42C 07B JNC    +0F B43B  got seed in buffer
B42D 389 *
B42E 140 NCXQ   50E2 =ENTMR, enable Timer, disable RAM
B42F 038 RDATA               get seed from clock
B430 05A C=0    M
B431 07C RCR    4
B432 3F0 PERSLCT
B433 2A0 SETDEC
B434 266 C=C-1  X
B435 158 M=C
B436 0A6 A<>C   X
B437 270 RAMSLCT
B438 375 *
B439 03C NCXQ   0FDD =GOSUBH
B43A 015 *             => B415, save seed from clock
B43B 0FC RCR    10
B43C 046 C=0    X
B43D 07C RCR    4
B43E 2A0 SETDEC
B43F 10E A=C    ALL
B440 04E C=0    ALL
B441 35C PT=    12
B442 250 LC     9
B443 210 LC     8
B444 090 LC     2
B445 050 LC     1
B446 130 LDI
B447 003 CON    03           9821e3
B448 135 *
B449 060 NCXQ   184D =MP2_10, multiply
B44A 10E A=C    ALL
B44B 04E C=0    ALL
B44C 19C PT=    11
B44D 090 LC     2
B44E 050 LC     1
B44F 050 LC     1
B450 0D0 LC     3
B451 090 LC     2
B452 1D0 LC     7           ,211327
B453 01D *
B454 060 NCXQ   1807 =AD2_10, add
B455 084 CF     5
B456 0ED *
B457 064 NCXQ   193B =INTFRC, keep fraction only
B458 158 M=C
B459 0EE B<>C   ALL
B45A 375 *
B45B 03C NCXQ   0FDD =GOSUBH
B45C 01A *             => B41A, save as new seed
B45D 0B9 *
B45E 04A NCGO   122E =RCL, put RN on stack
* * * End of File * * *
Ciao.....Mike
Find all posts by this user
Quote this message in a reply
12-08-2017, 04:26 AM (This post was last modified: 12-08-2017 04:33 AM by Trond.)
Post: #22
RE: HP41C random number generator help
(12-05-2017 12:30 PM)Namir Wrote:  A good and simple algorithm (used by HP since the HP-65 Stat Pacs) is:

r = frac(997 * r)

Code:
LBL "RAND"
RCL 00
997
*
FRC
STO 00
RTN

In my HHC2017 presentation about PRNGs, I pointed out that the above legacy algorithm is recommended for its speed, simplicity, and relatively good results for calculators.

Namir
I tried a version of this while trying to avoid "bad seeds". I built a program that first checks if the variable 00 has anything above 0 beyond the fifth decimal point, and if not it adds pi, then goes on to multiply with 997, does FRC and STO 00. If 00 does have a digit at the fifth decimal it will simply do the last three steps. Looks to work fine for me, but it is no longer as simple of course.
Find all posts by this user
Quote this message in a reply
12-08-2017, 07:43 PM
Post: #23
RE: HP41C random number generator help
(12-08-2017 04:26 AM)Trond Wrote:  I tried a version of this while trying to avoid "bad seeds". I built a program that first checks if the variable 00 has anything above 0 beyond the fifth decimal point, and if not it adds pi, then goes on to multiply with 997, does FRC and STO 00. If 00 does have a digit at the fifth decimal it will simply do the last three steps. Looks to work fine for me, but it is no longer as simple of course.

Why don't you simply do it ...right? There is a clear definition of the minimal properties that have to be met: seven decimals, and the last one must be 1, 3, 7 or 9. This can be done with the following SEED code:

Code:
LBL"SEED"
ABS
FRC
1E6
*
INT
,3
+
1E6
/
STO 00
RTN

Enter a seed, XEQ "SEED", and if neccessary the input is corrected.
Example: pi => 0,1415923

Yes, this simply sets the 7th decimal to 3 even if it was another valid digit like 1, 7 or 9 before. ;-)

Dieter
Find all posts by this user
Quote this message in a reply
12-08-2017, 09:17 PM (This post was last modified: 12-08-2017 09:18 PM by Trond.)
Post: #24
RE: HP41C random number generator help
(12-08-2017 07:43 PM)Dieter Wrote:  Why don't you simply do it ...right? There is a clear definition of the minimal properties that have to be met: seven decimals, and the last one must be 1, 3, 7 or 9. This can be done with the following SEED code:

I guess I missed the 1, 3, 7, 9 part, but yes I meant beyond the sixth decimal (do we have this written down somewhere? You seemed uncertain too). I was thinking not to change the seed if it's not necessary, but well, not sure how often it matters. But I also wanted to replace seeds that always predictably produce numbers that start with 0 in the first few decimals. Very small seeds will always start up with 0 in their first few decimals, and this includes the seed 0.0000003 which will be common (since the variable having a 0 stored is common). Having said that, my other random number generator program is working fine so, no big issue there. It was just a bit fascinating with the simplicity of multiplying with one number.
Find all posts by this user
Quote this message in a reply
12-08-2017, 09:56 PM (This post was last modified: 12-08-2017 10:04 PM by Dieter.)
Post: #25
RE: HP41C random number generator help
(12-08-2017 09:17 PM)Trond Wrote:  I guess I missed the 1, 3, 7, 9 part, but yes I meant beyond the sixth decimal (do we have this written down somewhere? You seemed uncertain too).

As already noted, an article in PPC Journal V4N8 by Victor K. Heyman takes a close look at four popular PRNGs, among them the 997x generator. The article mentions 11 different tests, even some quite sophisticated ones. Here it says:

Quote:With the proper seed, this generator has a cylce of 500,000 iterations. HP chose pretty well when it selected .5284163. It is supposed to pass all standard tests, and with a blink or two, it does. That is a tough seed to remember, and worse to program, so I have found one that is as good and much easier on the user: Pi, Sin, Tan. It works, and also follows all the rules -- the seed must have seven digits after multiplying by 997, the 7th not divisible by 2 or 5. (...) However every seed that meets the rule is not good.

"Not divisible by 2 or 5" means 1, 3, 7 or 9 for the seed's last digit. And that's exactly what the 997x generator produces.

Dieter
Find all posts by this user
Quote this message in a reply
12-09-2017, 09:53 PM
Post: #26
RE: HP41C random number generator help
(12-08-2017 07:43 PM)Dieter Wrote:  Yes, this simply sets the 7th decimal to 3 even if it was another valid digit like 1, 7 or 9 before. ;-)

OK-OK, here is a version that adjust the input only when required.

Code:
LBL "SEED997"
ABS
FRC
1E7
*
INT
RCL X
2
MOD
-
1
+
RCL X
5
MOD
X≠0?
SIGN
ST+ X
-
2
+
1E7
/
STO 00
RTN

Example:
0,1234567 XEQ"SEED997" => 0,1234567
0,2222222 XEQ"SEED997" => 0,2222223

Dieter
Find all posts by this user
Quote this message in a reply
12-10-2017, 04:09 AM
Post: #27
RE: HP41C random number generator help
(12-09-2017 09:53 PM)Dieter Wrote:  
(12-08-2017 07:43 PM)Dieter Wrote:  Yes, this simply sets the 7th decimal to 3 even if it was another valid digit like 1, 7 or 9 before. ;-)

OK-OK, here is a version that adjust the input only when required.

Code:
LBL "SEED997"
ABS
FRC
1E7
*
INT
RCL X
2
MOD
-
1
+
RCL X
5
MOD
X≠0?
SIGN
ST+ X
-
2
+
1E7
/
STO 00
RTN

Example:
0,1234567 XEQ"SEED997" => 0,1234567
0,2222222 XEQ"SEED997" => 0,2222223

Dieter

Taking things as a challenge is a good thing! Smile OK I will try this one.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)