在Excel VBA中找到Rnd的好替代品

在Excel VBA中找到Rnd的好替代品,excel,vba,random,numbers,Excel,Vba,Random,Numbers,众所周知,Excel中的Rnd函数很弱,而Excel中的RAND函数基于Mersenne算法,更强大。我一直在尝试寻找一种快速而强大的Rnd替代方案,并研究了各种选项,包括使用Mersenne,但这需要大量代码。另一个选项是从VBA调用Excel RAND函数,但每次调用一个函数时速度非常慢。但是,Excel 365中的新函数RANDARRAY允许VBA一次调用Excel中的大量随机数,根据需要使用它们,并在必要时返回以获取更多。这种方法速度快(仅比Rnd慢4倍,比Mersenne代码快)且紧凑

众所周知,Excel中的Rnd函数很弱,而Excel中的RAND函数基于Mersenne算法,更强大。我一直在尝试寻找一种快速而强大的Rnd替代方案,并研究了各种选项,包括使用Mersenne,但这需要大量代码。

另一个选项是从VBA调用Excel RAND函数,但每次调用一个函数时速度非常慢。但是,Excel 365中的新函数RANDARRAY允许VBA一次调用Excel中的大量随机数,根据需要使用它们,并在必要时返回以获取更多。这种方法速度快(仅比Rnd慢4倍,比Mersenne代码快)且紧凑-代码如下

我分享这一点是希望找到解决这个问题的最佳集体方案

Function RandXL() As Single
  Static Remaining As Long, R() As Variant
  If Remaining = 0 Then 'get more numbers if necessary
    R = Application.WorksheetFunction.RandArray(1000, 1)
    Remaining = 1000
  End If
  RandXL = R(Remaining, 1)
  Remaining = Remaining - 1
End Function

您可以使用真正的随机数-如我的项目所示

它包含Rnd的直接替代品:

”以双精度返回真随机数,就像Rnd返回单精度一样。
'该值将小于1但大于或等于零。
'
'用法:非常像Rnd:
'
'TrueRandomValue=RndQrn[(数字)]
'
'Number<0->每次使用相同的数字作为种子。
'Number>0->伪随机序列中的下一个数字。
'Number=0->最近生成的编号。
'无数字->伪随机序列中的下一个数字。
'
' 2019-12-21. 古斯塔夫·布罗克,仙人掌数据ApS,CPH。
'
公共职能RndQrn(_
可选的ByVal编号(单个=1)_
加倍
静态值为双精度
选择案例编号
大小写>0或(数字=0,值=0)
'返回随机序列中的下一个数字。
值=CDbl(qrnecimal)
大小写为=0
'返回最近生成的号码。
病例<0
'不受QRN支持。
'从RndDbl检索值。
值=RndDbl(编号)
结束选择
'返回如下值:
' 0.171394365283966
RndQrn=值
端函数
此外,还提供了一个演示(
RandomQrn.xlsm
)供下载

这设置了对使用Nz函数的Microsoft Access 16.0对象库的引用。如果您不希望有此参考,此替代品可以:

替换Access的函数Application.Nz()。 ' ' 2015-12-10. 古斯塔夫·布罗克,仙人掌数据ApS,CPH。 ' 公共职能新西兰(_ ByRef值作为变量_ 可选ByRef ValueIfNull作为变量“”)_ 作为变体 作为变量的Dim ValueNz 如果不是空的(值),则 如果为空(值),则 ValueNz=ValueIfNull 其他的 ValueNz=值 如果结束 如果结束 Nz=ValueNz 端函数
我有一个基于此的算法(我得到的是很久以前的某个地方):。如果有帮助的话,我可以抄下来作为答案。谢谢,我已经看过了,而且速度很快,但我不知道它有多可靠。如果使用Mersene是唯一的问题,那就是它需要大量的编码。我在这页上找到了一个版本:谢谢,古斯塔夫。它似乎通过web查询来检索随机数。我不认为这会很快,如果你没有互联网连接,或者你的网站关闭了,你会怎么做?它与所有随机性测试套件(如Diehard)配合得如何?这取决于你的体重“快”和“强”如何,以及你如何测量——我们不知道。请注意,您可以以数组的形式检索一批数字,这是VBA中最快的集合。至于随机性,请研究我在文档中提供链接的来源。如果你不能依靠互联网连接——这在现在看起来很奇怪——去Quantis购买add inn PCI卡;这也将提供最终的速度(以成本为代价)。代码在看到Nz未定义2时抛出错误。您的文档没有使用任何标准测试套件测试该方法。演示已将参考设置为访问新西兰-请参阅编辑的答案。另外,请理解,我的项目的目标不是证明源代码的随机性(我没有理由怀疑),而是展示如何在VBA中轻松利用这个伟大的源代码,特别是Access和Excel。如果您碰巧运行了这些测试中的任何一个,我很乐意将结果包含在文档中。这是一个好主意,不是我想要的,但是其他人可能需要非常高质量的随机性。我建议运行一些正式的随机性测试,以确保它像您认为的那样随机,并且在实现中没有错误。