'種を使って初期化できます。116よりさらに2倍程度高速になりました
Private Const p32 = 2# ^ 32, p31 = 2# ^ 31, p21 = 2# ^ 21, p11 = 2# ^ 11
Private Const m53 = 2# ^ -53, m32 = 2# ^ -32, m30 = 2# ^ -30, m19 = 2# ^ -19, m11 = 2# ^ -11, m8 = 2# ^ -8
Private x, y, z, w As Double
Private f As Boolean
Private Function uXor(ByVal x As Double, ByVal y As Double) As Double
Dim u, v As Long
If x >= p31 Then u = x - p32 Else u = x
If y >= p31 Then v = y - p32 Else v = y
u = u Xor v
If u < 0 Then uXor = u + p32 Else uXor = u
End Function
Private Function XSub(ByVal x As Double, ByVal i As Long) As Double
Dim s As Variant
s = CDec(1812433253) * CDec(uXor(x, Int(x * m30))) + CDec(i): s = s - CDec(Int(s * m32)) * CDec(p32): XSub = s
End Function
Public Sub InitXor(ByVal s As Long) ' s を種にして乱数を初期化する
f = True: x = XSub(s, 1): y = XSub(x, 2): z = XSub(y, 3): w = XSub(z, 4)
End Sub
Private Function NextXor() As Double
Dim t As Double
If f = 0 Then InitXor (1)
t = x * p11: t = t - Int(t * m32) * p32: t = uXor(x, t): x = y: y = z: z = w: t = uXor(t, Int(t * m8)): w = uXor(uXor(w, Int(w * m19)), t): NextXor = w
End Function
Public Function NextUnif() As Double ' 0 以上 1 未満の乱数を返す
Dim x, y As Double
x = NextXor * m11: y = NextXor: NextUnif = (y * p21 + Int(x)) * m53
End Function