Algorithm Implementation/Pseudorandom Numbers

From Wikibooks, open books for an open world
Jump to: navigation, search

Wichmann-Hill (1982) PRNG[edit]

VBA Code[edit]

This algorithm has behavior that is broadly similar to that of the built-in VBA Rnd() function, and this is perhaps not surprising since it was the basis of the Excel Rand() function for quite some time.*The Randomize() function is used to set the working variables located at module level. In turn, these variables are used at every stage to calculate RndX() outputs and to re-calculate their own values, ready for the next RndX() call.

Option Explicit
Dim nX As Long, nY As Long, nZ As Long

Sub TestRndX()
    Dim n As Long
    RandomizeX
    For n = 1 To 1000
        'Debug.Print RndX()
        MsgBox RndX()    
    Next n
End Sub

Sub RandomizeX(Optional ByVal nSeed As Variant)
   'sets variables for PRNG procedure RndX()
      
   Const MaxLong As Double = 2 ^ 31 - 1
   Dim nS As Long
   Dim nN As Double
   
   'make multiplier
   If IsMissing(nSeed) Then
      nS = Timer * 60
   Else
      nN = Abs(Int(Val(nSeed)))
      If nN > MaxLong Then 'no overflow
         nN = nN - Int(nN / MaxLong) * MaxLong
      End If
      nS = nN
   End If
   
   'update variables
   nX = (nS Mod 30269)
   nY = (nS Mod 30307)
   nZ = (nS Mod 30323)
   
   'avoid zero state
   If nX = 0 Then nX = 171
   If nY = 0 Then nY = 172
   If nZ = 0 Then nZ = 170

End Sub

Function RndX(Optional ByVal nSeed As Long = 1) As Double
   'PRNG - gets pseudo random number - use with RandomizeX
   'Wichmann-Hill algorithm of 1982
   
   Dim nResult As Double
   
   'initialize variables
   If nX = 0 Then
      nX = 171
      nY = 172
      nZ = 170
   End If
   
   'first update variables
   If nSeed <> 0 Then
      If nSeed < 0 Then RandomizeX (nSeed)
      nX = (171 * nX) Mod 30269
      nY = (172 * nY) Mod 30307
      nZ = (170 * nZ) Mod 30323
   End If
   
   'use variables to calculate output
   nResult = nX / 30269# + nY / 30307# + nZ / 30323#
   RndX = nResult - Int(nResult)

End Function

See Also[edit]

References[edit]

  • Wichmann, Brian; Hill, David (1982), Algorithm AS183: An Efficient and Portable Pseudo-Random Number Generator, Journal of the Royal Statistical Society. Series C