VBA rand如何使用上限和下限生成随机数?

时间:2016-07-12 17:11:23

标签: excel vba excel-vba random

所以也许这是多余的,也许就像问为什么大多数人天生就有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参数呢?我不可能是唯一一个看着这个公式的人,那个世界是什么?

在一天结束时,它对我的​​任何伪随机数的需求当然都很好,也许我正在寻找一个礼物马,但仍然!

修改

我觉得这个问题可能基于数学本身。如果你取一个小整数,你应用什么函数来使整数适合指定范围..所以任何人都可以解释这个公式是如何工作的?

4 个答案:

答案 0 :(得分:9)

这是一步一步的指南:

  1. 6 * Rnd给出0和<之间的随机小数。 1
  2. Int(6 * Rnd)给出0和<之间的随机小数。 6
  3. RANDBETWEEN围绕向下,以便获得0到5之间的随机值
  4. 在下限和上限之间生成随机数非常常见。 Excel确实有Value = WorksheetFunction.RandBetween(1, 6) 函数来执行此操作:

    Lbound

    修改现在让它适合UboundLbound < 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已经有了正确的答案。这只适用于第一眼看不到它的人

  1. Excel仅生成0到1之间的随机数
  2. 通过将步骤1中生成的随机数乘以x数字,我们可以获得0x之间的值
  3. 那怎么样?

    Int ((upperbound - lowerbound + 1) * Rnd + lowerbound)

    在上限和下限之间生成一个随机数

    1. 在最后一步中,您提供了在步骤1中生成的随机数乘以的数字x。在这里,为了生成此数字x,您执行upperbound - lowerbound以便{ {1}}从random_number到两个数字的差异,即(0)生成。现在,如果您将较小的数字upperbound - lowerbound添加到lowerbound,它将生成总和大于random_number&amp;小于lowerbound