基于VBA的线性同余发生器

基于VBA的线性同余发生器,vba,excel,random,Vba,Excel,Random,我试图在VBA中复制线性同余生成器,但我的过程返回错误“6”:溢出 Sub test() Dim a As Long, c As Long, period As Long Dim seed As Long, sample As Long, max As Long Dim i As Long seed = 1234 sample = 2 max = 100 a = 48271 c = 0 period = 2 ^ 31

我试图在VBA中复制线性同余生成器,但我的过程返回错误“6”:溢出

Sub test()
    Dim a As Long, c As Long, period As Long
    Dim seed As Long, sample As Long, max As Long
    Dim i  As Long

    seed = 1234
    sample = 2
    max = 100

    a = 48271
    c = 0
    period = 2 ^ 31 - 1

    For i = 1 To sample
        seed = (a * seed + c) Mod period
    Next i
End Sub
我认为问题出在for循环的第一个表达式中

a*seed
在循环的第二步。 有没有不分裂地解决问题的建议

a*seed

您可以使用of variant并为小数编写自己的mod函数:

Function DecMod(a As Variant, n As Variant) As Variant
    Dim q As Variant
    q = Int(CDec(a) / CDec(n))
    DecMod = a - n * q
End Function

Sub test()
    Dim a As Variant, c As Variant, period As Variant
    Dim seed As Variant, sample As Long, max As Long
    Dim i  As Long

    seed = CDec(1234)
    sample = 5
    max = 100

    a = CDec(48271)
    c = 0
    period = CDec(2 ^ 31 - 1)

    For i = 1 To sample
        Debug.Print seed
        seed = DecMod(seed * a + c, period)
    Next i
End Sub
输出:

1234 
59566414 
1997250508 
148423250 
533254358 

@CallumDA我已经尝试将每个数字声明为一样长,但仍然会溢出调试函数说seed=(a*seed+c)Mod period我已经更新了你的问题,因此代码是最小的,并且可以立即重复——因为我已经更新了声明,问题仍然存在,所以我现在也删除了我的答案OK,非常感谢@马修金登,是的。我将
seed=
替换为
Debug.Print
,效果很好-输出为
59566414
。在
Long
良好的解决方案(+1)的范围内。。。难道你不知道最初溢出的原因吗?我真的希望得到一个解释@在原始代码中(使用
Long
),当VBA尝试将
1234*59566414
作为Long求值时,溢出在循环的第二次传递中发生。如果其中一个操作数溢出,则即使生成的
Mod
没有溢出,整个计算也会溢出。如果
Mod
的实现更加健壮,那就太好了。
1234 
59566414 
1997250508 
148423250 
533254358