Random Number Generation
Posted: Wed Mar 13, 2019 9:05 am
Hi,
Just over a year ago, I needed large random numbers, so I tried to write my own code to do generate them.
Finally, after much statistical testing, I obtained results as good as the Sinclair ROM RND() functions.
The listing produces screen output to compare the two sets of functions.
Of course you can get large random numbers by concatenating smaller ones, but you may find the core routines interesting.
Regards,
Steve Poole.
100 ::
110 REMark QLforum_random_bas v12mar19
120 REMark Calculates random numbers:
130 REMark core code is in function r()
140 :
150 CLEAR
160 bc=1: q$='': FOR f=1 TO 5: q$=q$&R$
170 IF q$>65537: GO TO 160: ELSE q=q$
180 WINDOW 256,256,256,0: PAPER 0: CLS
190 WINDOW#2,256,256,0,0: PAPER#2,0: CLS#2
200 screen_test : INK#2,7: INK 7
210 PRINT#2, 'QL ROM..': PRINT 'SBasic..'
220 PAUSE 500: GO TO 160
230 ::
240 DEFine PROCedure screen_test
250 SCALE 127,0,0: SCALE#2,127,0,0
260 FOR ch=1,2
270 FOR i=1 TO 16384
280 IF ch=2
290 x=RaND_int(127): y=RaND_int(127)
300 INK#ch, RaND_int(7)
310 ELSE x=RND(127): y=RND(127)
320 INK#ch, RND(7)
330 END IF
340 FILL#ch,1: CIRCLE#ch,x,y,.6: FILL#ch,0
350 END FOR i
360 END FOR ch
370 END DEFine
380 ::
390 DEFine FuNction r(d)
400 LOCal k,c,g
410 REMark random generator 0 to 65537:
420 c=8421: g=65537
430 k=d*c+1: k=k-(INT(k/g)*g)
440 RETurn INT(k)
450 END DEFine
460 :
470 DEFine FuNction R$
480 LOCal rs,kt: REMark PC reseeder:
490 BEEP 123,bc: bc=bc+1: IF bc>24: bc=1
500 REPeat rs
510 FOR kt=1 TO 10
520 IF BEEPING=0: EXIT rs
530 END FOR kt
540 END REPeat rs
550 RETurn '0123456789'(kt)
560 END DEFine
570 :
580 DEFine FuNction MOD_(ms,md)
590 REMark calculate MODulus:
600 RETurn ms-(INT(ms/md)*md)
610 END DEFine
620 :
630 DEFine FuNction RaND_int(mo)
640 REMark random integer (1 to 999999)
650 q=r(q): RETurn MOD_(q,mo+1)
660 END DEFine
670 ::
Just over a year ago, I needed large random numbers, so I tried to write my own code to do generate them.
Finally, after much statistical testing, I obtained results as good as the Sinclair ROM RND() functions.
The listing produces screen output to compare the two sets of functions.
Of course you can get large random numbers by concatenating smaller ones, but you may find the core routines interesting.
Regards,
Steve Poole.
100 ::
110 REMark QLforum_random_bas v12mar19
120 REMark Calculates random numbers:
130 REMark core code is in function r()
140 :
150 CLEAR
160 bc=1: q$='': FOR f=1 TO 5: q$=q$&R$
170 IF q$>65537: GO TO 160: ELSE q=q$
180 WINDOW 256,256,256,0: PAPER 0: CLS
190 WINDOW#2,256,256,0,0: PAPER#2,0: CLS#2
200 screen_test : INK#2,7: INK 7
210 PRINT#2, 'QL ROM..': PRINT 'SBasic..'
220 PAUSE 500: GO TO 160
230 ::
240 DEFine PROCedure screen_test
250 SCALE 127,0,0: SCALE#2,127,0,0
260 FOR ch=1,2
270 FOR i=1 TO 16384
280 IF ch=2
290 x=RaND_int(127): y=RaND_int(127)
300 INK#ch, RaND_int(7)
310 ELSE x=RND(127): y=RND(127)
320 INK#ch, RND(7)
330 END IF
340 FILL#ch,1: CIRCLE#ch,x,y,.6: FILL#ch,0
350 END FOR i
360 END FOR ch
370 END DEFine
380 ::
390 DEFine FuNction r(d)
400 LOCal k,c,g
410 REMark random generator 0 to 65537:
420 c=8421: g=65537
430 k=d*c+1: k=k-(INT(k/g)*g)
440 RETurn INT(k)
450 END DEFine
460 :
470 DEFine FuNction R$
480 LOCal rs,kt: REMark PC reseeder:
490 BEEP 123,bc: bc=bc+1: IF bc>24: bc=1
500 REPeat rs
510 FOR kt=1 TO 10
520 IF BEEPING=0: EXIT rs
530 END FOR kt
540 END REPeat rs
550 RETurn '0123456789'(kt)
560 END DEFine
570 :
580 DEFine FuNction MOD_(ms,md)
590 REMark calculate MODulus:
600 RETurn ms-(INT(ms/md)*md)
610 END DEFine
620 :
630 DEFine FuNction RaND_int(mo)
640 REMark random integer (1 to 999999)
650 q=r(q): RETurn MOD_(q,mo+1)
660 END DEFine
670 ::