所以也许这是多余的,也许就像问为什么大多数人天生就有5个手指,最后简短的回答总是:因为它就是这样,它只是起作用,但我讨厌这个答案并且该死我想要知道VBA中的Rnd()函数是如何工作的。
Ms Office Excel的MSDN表示RND定义为:
Rnd[(number)] 'The optional number argument is a Single or any valid numeric expression.
接着说
“数字的值决定了Rnd如何生成一个随机数:For 任何给定的初始种子,都会生成相同的数字序列,因为 每次连续调用Rnd函数都使用前一个数字作为 种子为序列中的下一个数字。“
接着是:
要在给定范围内生成随机整数,请使用以下公式:
Int((upperbound - lowerbound + 1) * Rnd + lowerbound)
所以例如:
Dim MyValue
MyValue = Int((6 * Rnd) + 1) ' Generate random value between 1 and 6.
但这怎么办?这些数字来自哪里?为什么6 * Rnd + 1
会获得1到6之间的随机数,但是6 * Rnd + 5
会得到5到10之间的数字?
此外,如果VBA的创建者使用什么公式来成功地将其缩小到特定范围,那么为什么不让RND函数带有可选的Ubound和Lbound参数呢?我不可能是唯一一个看着这个公式的人,那个世界是什么?
在一天结束时,它对我的任何伪随机数的需求当然都很好,也许我正在寻找一个礼物马,但仍然!
修改
我觉得这个问题可能基于数学本身。如果你取一个小整数,你应用什么函数来使整数适合指定范围..所以任何人都可以解释这个公式是如何工作的?
答案 0 :(得分:9)
这是一步一步的指南:
6 * Rnd
给出0和<之间的随机小数。 1 Int(6 * Rnd)
给出0和<之间的随机小数。 6 RANDBETWEEN
围绕向下,以便获得0到5之间的随机值在下限和上限之间生成随机数非常常见。 Excel确实有Value = WorksheetFunction.RandBetween(1, 6)
函数来执行此操作:
Lbound
修改现在让它适合Ubound
和Lbound < Ubound
(假设两者都是整数和n = ubound - lbound
)
首先,定义:
Int((ubound - lbound + 1) * Rnd + lbound)
== Int((ubound - lbound + 1) * Rnd) + lbound
== Int(((n + 1) * Rnd) + lbound
接下来,我们将略微重写MSDN公式:
Int(((n + 1) * Rnd)
从#3开始,我们知道 Int(((n + 1) * Rnd) + lbound
== 0...n + lbound
== lbound...ubound
给出0到n之间的随机整数。因此,当您将该随机数添加到下限时,您会在下限和上限之间得到一个数字;
.effect-1:after {position: absolute;}
答案 1 :(得分:1)
使用类似RndBetween的公式,例如make_random_old = CLng((up - down + 1) * Rnd + down)
这是非常错误的(30分钟调试我的生活是了解它的代价!):)
您可以在此处使用Sub TestMe检查原因:
Public Sub testme()
Dim l_counter As Long
Dim l_random As Long
For l_counter = 0 To 10000
l_random = make_random_old(0, 2)
If l_random = 3 Then Debug.Print l_random
Next l_counter
Debug.Print "END"
End Sub
Public Function make_random(down As Long, up As Long) As Long
make_random = CLng((up - down + 1) * Rnd + down)
If make_random > up Then make_random = up
If make_random < down Then make_random = down
End Function
Public Function make_random_old(down As Long, up As Long) As Long
make_random_old = CLng((up - down + 1) * Rnd + down)
End Function
作为RndBetweem中一些随机的解决方法,请使用make_random
- 代码中的第二个函数。
它会为您节省很多问题。 :)
答案 2 :(得分:0)
这可能会让它更清晰:Rnd返回一个0到<1范围内的随机数(它是一个单一的 - 也就是一个分数,所以你有各种0.3948,0.001,0.8等等 - - 均匀分布的伪随机数)。该函数中的参数旨在用于“易用性”和#34;在公式和算法中,但可以说不适合休闲用户。
通常,Rnd实际上遵循许多(如果不是所有的)编程语言(即,生成从0.0到<1.0的随机分数)的随机数生成器API如何暴露的事实标准。因此,如果你从VBA到Python再到Java再到C - 你将会看到它在工作方式上的惊人相似之处。
话虽如此,许多语言(例如,Python)为核心Rnd函数提供了更高级别的包装器,因此在基本方案中更容易使用。 VBA是一种非常古老的语言 - 很少被微软更新(这是一种祝福和诅咒),所以如果你需要辅助功能,你必须自己动手。
您可以使用以下内容:
Function RndBetween(lowerbound As Int, upperbound As Int) As Int
RndBetween = Int((upperbound - lowerbound + 1) * Rnd + lowerbound)
End Function
在你的代码中它变得简单:
RndBetween(1, 6)
一段时间后,您将拥有一个辅助函数模块,这将使生活更轻松,代码更具可读性。在那之前...... StackOverflow: - )
答案 3 :(得分:0)
@Code Different已经有了正确的答案。这只适用于第一眼看不到它的人
x
数字,我们可以获得0
和x
之间的值那怎么样?
Int ((upperbound - lowerbound + 1) * Rnd + lowerbound)
在上限和下限之间生成一个随机数
x
。在这里,为了生成此数字x
,您执行upperbound - lowerbound
以便{ {1}}从random_number
到两个数字的差异,即(0
)生成。现在,如果您将较小的数字upperbound - lowerbound
添加到lowerbound
,它将生成总和大于random_number
&amp;小于lowerbound