Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Alternative random number generator
#1
The following RNG seems to perform better than the built-in RNG when tested with the DIEHARD battery of tests (http://stat.fsu.edu/pub/diehard/)

Code:
' ******************************************************************
' Marsaglia's 'Multiply with carry' random number generator
' ******************************************************************

OPTION EXPLICIT

' ------------------------------------------------------------------
' Global constant and variables
' ------------------------------------------------------------------

CONST Z = 2.3283064365386962890625D-10  ' 1/(2^32)

DIM SHARED AS UINTEGER X = 123456789UL  ' Seed
DIM SHARED AS UINTEGER C = 0            ' Carry

' ******************************************************************

SUB InitMWC(Seed AS UINTEGER)
' ------------------------------------------------------------------
' Initializes the generator
' ------------------------------------------------------------------

  X = Seed
  C = 0
END SUB

FUNCTION IRanMWC AS UINTEGER
' ------------------------------------------------------------------
' Returns a 32-bit unsigned random integer
' ------------------------------------------------------------------

  DIM AS ULONGINT Y

  Y = 2051013963ULL * X + C
  X = Y AND 4294967295ULL
  C = Y SHR 32ULL
  IRanMWC = X
END FUNCTION

FUNCTION RanMWC AS DOUBLE
' ------------------------------------------------------------------
' Returns a random floating point number in [0,1)
' ------------------------------------------------------------------

  RanMWC = IRanMWC * Z
END FUNCTION

' ******************************************************************
' Demo program
' ******************************************************************
' This program picks 2000 random numbers and displays the next 6
' together with the correct values obtained with the default
' initialization, i.e. InitMWC(123456789). The correct values
' have been checked with the Maple software.
' ******************************************************************

DIM AS UINTEGER Correct(1 TO 6) => _
{2315938931, _
2221963912, _
  795854508, _
2024400257, _
1291639274, _
3483712032}

DIM AS UINTEGER I, R

PRINT
PRINT "Test of MWC random number generator"
PRINT "-------------------------------------"
PRINT "       Correct        Actual"
PRINT "-------------------------------------"

' Pick 2000 random numbers
FOR I = 1 TO 2000: R = IRanMWC: NEXT

' Display 6 more numbers with correct values
FOR I = 1 TO 6
  R = IRanMWC
  PRINT USING "##############"; Correct(I); R;
  IF Correct(I) = R THEN PRINT "    OK" ELSE PRINT "    BAD"
NEXT I
PRINT "-------------------------------------"

DO : LOOP UNTIL INKEY$ <> ""
ean Debord
----------------
Math library for FreeBasic:
http://www.unilim.fr/pages_perso/jean.de...fbmath.zip
Reply
#2
FB's RNG is much better than QB's, at least it passes my silly test, QB didn't. Run this code in both, QB displays PATTERNS for a modulu of 4.
Code:
screen 12
i = 0
DO
CLS
LOCATE , 1
PRINT "Testing QB's RND with modulus "; i + 3; "Press a key for next, ESC to exit"
DO
    PSET (RND * 256 + 200, RND * 256 + 100), RND * 16
  
    FOR j = 1 TO i: a! = RND: NEXT
    k$ = INKEY$
LOOP UNTIL LEN(k$)
i = i + 1
LOOP UNTIL ASC(k$) = 27

end
I don't pretend to compare my test with Diehard Big Grin..Criptographers will like an even better RND!
Antoni
Reply
#3
Yes, the patterns are quite visible in QB when the modulus is a multiple of 4 !

BTW, the MWC generator which I posted passes your test... Smile

I cannot guarantee that it is safe enough for cryptography, though...
ean Debord
----------------
Math library for FreeBasic:
http://www.unilim.fr/pages_perso/jean.de...fbmath.zip
Reply
#4
I made a RND function a while ago for FB:

Code:
function getRND (precission as uinteger = 703) as single
    static lastnum as single
    dd = (((timer*1000) mod 255000)) mod 65536
    aa! = dd
    aa! = aa! mod precission
    aa! = aa! / precission+lastnum
    while aa! > 1
        aa!=aa!-1
    wend
    lastnum = aa!
    getRND = aa!
end function
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)