Mersenne Twister - Out of range exception

161 views Asked by At

In a VB.NET implementation of the Mersenne Twister, I am getting an out-of-range exception, which is being thrown periodically (error image screenshot below):

         Private Shared mt(312 - 1) As ULong
         Private Shared mti As ULong = 312 + 1


         Private Function genrand64_int64() As ULong
            On Error GoTo errhandler

            Dim i As Long
            Dim x As ULong
            Static mag01() As ULong = {0UL, MATRIX_A}

            If mti >= NN Then ' generate NN words at one time

                ' if init_genrand64() has not been called, 
                ' a default initial seed is used     
                If mti = NN + 1 Then
                    init_genrand64(5489UL)
                End If

                i = 0
                Do While i < NN - MM
                    x = (mt(i) And UM) Or (mt(i + 1) And LM)
                    mt(i) = mt(i + MM) Xor (x >> 1) Xor mag01(CInt(x And 1UL))
                    i += 1
                Loop
                Do While i < NN - 1
                    x = (mt(i) And UM) Or (mt(i + 1) And LM)
                    mt(i) = mt(i + (MM - NN)) Xor (x >> 1) Xor mag01(CInt(x And 1UL))
                    i += 1
                Loop
                x = (mt(NN - 1) And UM) Or (mt(0) And LM)
                mt(NN - 1) = mt(MM - 1) Xor (x >> 1) Xor mag01(CInt(x And 1UL))

                mti = 0
            End If

            x = mt(mti)   '<<<<<<<<<<<HERE<<<<<<<<<<<<<<<<<<<<<<
            mti += 1

            x = x Xor (x >> 29) And &H5555555555555555UL
            x = x Xor (x << 17) And &H71D67FFFEDA60000UL
            x = x Xor (x << 37) And &HFFF7EEE000000000UL
            x = x Xor (x >> 43)

            Return x
         End Function

Specifically, the exception is as follows:

enter image description here

Note that the mt() vector checks out OK with 312 elements, and during the exception the index value of mti=42, 86, or 212, well within the range of 312. Is the value of x too large?

The init is:

   Sub init_genrand64(ByVal seed As ULong)
     mt(0) = seed
     For mti = 1 To NN - 1
       mt(mti) = (6364136223846793005UL * (mt(mti - 1) Xor (mt(mti - 1) >> 62)) + mti)
     Next mti
   End Sub
0

There are 0 answers