Minor change made so that it is "NoVarsInStrings" safe.
I'm not convinced that there is a repeating pattern, though you will need a larger sample to prove it.
The script below graphs the results from the RNG. You will see that the results are fairly linear, which indicates a good spread of values. More importantly, the pattern of growth changes - I'd expect a repeating set to have both an unbalanced set returned and an obvious pattern of growth.
Try changing the $iSampleSet value (to a multiple of 50). After subtracting $iBase, the process will plot
- $iSampleSet=50 Every result
- $iSampleSet=100 Even numbers
- $iSampleSet=250 Numbers divisible by 5
- $iSampleSet=5000 Hundreds
...and so on.
It's not a mathematical proof (my maths ain't that good) but it looks ok from an empirical standpoint.
I've got another algorithm somewhere, but it needs large number support. I'll dig it out next chance I get to spend some more time on this.
Code:
Break ON
$=SetOption("Explicit","ON")
$=SetOption("ASCII","ON")
$=SetOption("NoVarsInStrings","ON")
Dim $r,$iMaxScale,$iRow,$iSampleSize,$iSampleRate,$iBase,$iSampleCount
Dim $iResults[50]
$iMaxScale=100
$iSampleSize=5000
$iBase=1234
CLS
DrawGraph($iMaxScale,$iResults)
$iSampleSize=Int($iSampleSize/50)*50
At(23,40) "Sample size=" $iSampleSize ", Base=" $iBase
$iSampleRate=$iSampleSize/50
$r=rng(0,0,@TICKS)
While "TRUE" AND Not KBHit()
$r=rng($iBase,$iBase+$iSampleSize-1)
$iSampleCount=$iSampleCount+1
$r=$r-$iBase
; Only record results from sample
If Not ($r mod $iSampleRate)
At(23,0) "Last: " $r " "
$r=$r/$iSampleRate
At(23,15) "Sample Count: " $iSampleCount
$iResults[$r]=$iResults[$r]+1
$iRow=$iResults[$r]/($iMaxScale/20)
If $iRow>20
$iMaxScale=$iMaxScale*2
DrawGraph($iMaxScale,$iResults)
Else
If Not (($r+1) mod 5) Color y+/n EndIf
If $iRow AT(22-$iRow,$r+11) "*" EndIf
Color w/n
EndIf
EndIf
Loop
Get $r
Function DrawGraph($iMaxScale,$iResults)
Dim $iRow,$iCol
At(1,0) Right(" "+$iMaxScale,9)
For $iRow = 1 to 21 At($iRow,10) "|" Next
At(22,10) "+"
For $iCol=0 to 49
If Not (($iCol+1) mod 5) Color y+/n EndIf
At(22,$iCol+11) "-"
For $iRow=1 to 20
At(22-$iRow,$iCol+11)
If ($iResults[$iCol]/($iMaxScale/20)) >= $iRow "*" Else " " EndIf
Next
Color w/n
Next
Exit 0
EndFunction
Function rng($iMin,$iMax,Optional $iSeed)
Dim $vDiscard,$sDecimal,$i,$iFactor
Dim $ ; Fixes problem with "NoVarsInStrings" set to "ON"
$sDecimal="."
; Establish how many decimals to use
If InStr($iMin,$sDecimal) $iFactor=Len($iMin)-InStrRev($iMin,$sDecimal) EndIf
If InStr($iMax,$sDecimal) $i=Len($iMax)-InStrRev($iMax,$sDecimal) EndIf
If $i>$iFactor $iFactor=$i EndIf
$iMax=CDbl($iMax) $iMin=CDbl($iMin)
$iFactor=CInt("1"+Left("000000",$iFactor))
; Ensure min and max are in the right order
If $iMax < $iMin $i=$iMin $iMin=$iMax $iMax=$i EndIf
$iMax=$iMax * $iFactor
$iMin=$iMin * $iFactor
; Fix max to base (0)
$iMax=($iMax-$iMin+1)
If Not IsDeclared($_RNG_PERSISTENT) Global $_RNG_PERSISTENT EndIf
If VarType($iSeed) $_RNG_PERSISTENT=CInt($iSeed) EndIf
$_RNG_PERSISTENT=1103515245*$_RNG_PERSISTENT+12345
; Emulate 16 bit shift right ($rng>>16)
$rng=DecToHex($_RNG_PERSISTENT)
$rng=SubStr($rng,2,Len($rng)-3)
If $rng="" $rng=0 EndIf
; Convert hex to Decimal and fix to scope
$vDiscard=Execute("$$rng=CDbl((((&"+$rng+") mod "+$iMax+") + "+$iMin+")) / "+$iFactor)
EndFunction