VBA的 随机数 rnd 和 randomize 如何配合使用? 伪随机数带来的问题,根据需要产生不同的随机数!

本文详细介绍了VBA中Rnd函数的使用,包括其语法、参数影响以及如何生成不同的随机数序列。Rnd(-1)会生成相同的随机数序列,Rnd(0)在程序运行中保持一致但重新运行会改变,Rnd(正数)每次都会产生不同的数。通过Randomize可以设置随机种子,从而改变随机数序列。理解这些原理对于控制VBA程序中的随机行为至关重要。
摘要由CSDN通过智能技术生成

目录

总结前置

1 VBA中直接使用 rnd,是一个公式计算出来的模拟(伪随机)

2 伪随机数会带来什么问题:永远是同一组随机数

3  关于 rnd 的语法

3.1 基本语法

3.2 基本用法

3.3   rnd 和 rnd(-1)  rnd(0)  rand(1)  参数负数,零,和正数

3.4 直接用 rnd 和 rnd(-1)  rnd(0)  rand(1)  的总结

3.4 如何每次随机都得到相同的随机序列呢?

3.4.1 使用  rnd  负数

3.4.2 一些其他的可能性

3.4.3 randomize 的意义

3.6 配合 randomize  直接用 rnd 和 rnd(-1)  rnd(0)  rand(1)  参数负数,零,和正数 

3.7 配合 randomize  直接用 rnd 和 rnd(-1)  rnd(0)  rand(1)的总结

4 总结


总结前置

  • 如果想永远生成相同的随机数,就用rnd(-1) 但是这么做没意义吧?
  • 如果想每次生成的随机数,本次程序运行结束前都一样,下次计算时不一样。就用  randmize  和 rnd(0)
  • 如果想永远生成不同的随机数,无论是序列内,还是在不同的环境重新运行都不同,就用   randmize  和 rnd(1) 或 randmize 和 rnd  缺省就可以。

1 VBA中直接使用 rnd,是一个公式计算出来的模拟(伪随机)

  • 什么叫伪随机
  • 随机数的生成是使用一个写定的公式,来模拟随机的感觉
  • 但是这个生成随机数的模拟公式 f(f(f(1)))  受第一个数影响很大,一般称为随机种子

  • 如何形象的理解伪随机数
  • 你就想象,你的随机函数,每次生成的都是 3.1415926 这个序列,先给你生成3 1 4 1 5 9 2 6.。。。,下次你重新,还是从3 1 4 1 5 9 2 6.。。。 开始

2 伪随机数会带来什么问题:永远是同一组随机数

  • 下面是一个对比测试
  • 都是同一段代码
  • 最左边的是,多次运行代码的结果,看起来每次随机的结果都不同
  • 中间的,是每次执行后,都点停止运行,再点开始运行,这样loop循环操作出的结果
  • 最右边的,是每次执行后,点3次运行,然后点停止运行,这样loop循环操作出的结果
  • 对比后,发现很神奇的结果
  1. VBA里默认用  rnd 随机,如果一直运行,其实能一直往下随机
  2. 但是随机出的这一串数其实每次都是固定的从第1个 0.7055475 开始,可以说这1串数是固定的!也就是,每次重新开始,都是这一串相同的数组!
  3. 也就是相当于,不同的时候,重新开始执行这个 rnd 随机,随机结果永远相同!
  4. 也就是这段代码,每次在不同的时候重新开始运行,总是生成相同的随机数序列!!!!

Sub t1111()

Debug.Print Rnd

End Sub

  • 参考内容
  • Rnd函数在产生随机数的时候,并不是真正的随机,而是通过一定的公式计算产生的随机,现在我们把那个计算产生随机数的公式叫做f(x),第一个x取值为1
  • 那么便会产生第一个随机数f(1),第2个随机数是在第一个随机数的基础上产生的即f(f(1)),依次类推,第3个随机数是f(f(f(1)))
  • 不难发现,第一个数1,对于产生的一系列随机数是非常重要的,这个1,我们称之为种子数,一个种子数就对应一系列的随机数,如果种子数不发生变化,那么便会生成一系列相同的随机数
  • 这段分析来自网上一个大神写的
  • 哪位能举几个例子说明一下 VBA中Randomize的作用,_百度知道

3  关于 rnd 的语法

3.1 基本语法

  • excel里用 rand()  和 randbetween()
  • VBA里用 rnd

Rnd[(number)]
可选的 number 参数是 Single 或任何有效的数值表达式。
返回值
如果 number 的值是        Rnd 生成
小于 0        每次都使用 number 作为随机数种子得到的相同结果。
大于 0        序列中的下一个随机数。
等于 0        最近生成的数。
省略        序列中的下一个随机数。
说明
Rnd 函数返回小于 1 但大于或等于 0 的值。
number 的值决定了 Rnd 生成随机数的方式。
对最初给定的种子都会生成相同的数列,因为每一次调用 Rnd 函数都用数列中的前一个数作为下一个数的种子。
在调用 Rnd 之前,先使用无参数的 Randomize 语句初始化随机数生成器,该生成器具有根据系统计时器得到的种子。
为了生成某个范围内的随机整数,可使用以下公式:
Int((upperbound - lowerbound + 1) * Rnd + lowerbound)
这里,upperbound 是随机数范围的上限,而 lowerbound 则是随机数范围的下限。
注意 若想得到重复的随机数序列,在使用具有数值参数的 Randomize 之前直接调用具有负参数值的 Rnd。使用具有同样 number 值的 Randomize 是不会得到重复的随机数序列的。

3.2 基本用法

  • 要知道  rnd() 是左闭右开区间   [0,1)
  • 如果要生成 a~b之间的随机数,一般是  int(a+ (b-a+1)*rnd())
  • 如果数太大,要给数加上 clng(a)

3.3   rnd 和 rnd(-1)  rnd(0)  rand(1)  参数负数,零,和正数

  • 测试下面3段代码,发现只有   rnd(2 ) 每次随机都变化
Sub TEST1()
  For i = 1 To 3
    Debug.Print Rnd(-1)
  Next
End Sub
Sub TEST2()
  For i = 1 To 3
    Debug.Print Rnd(0)
  Next
End Sub
Sub TEST3()
  For i = 1 To 10
    Debug.Print Rnd(2)
  Next
End Sub
  • 最左边是test1的结果
  • 其次是test2的结果
  • 第3个是test3 一直点运行的结果

     

3.4 直接用 rnd 和 rnd(-1)  rnd(0)  rand(1)  的总结

小于 0        每次都使用 number 作为随机数种子得到的相同结果。
大于 0        序列中的下一个随机数。
等于 0        最近生成的数。
省略        序列中的下一个随机数。

  •  rnd(-1) 永远 生成相同的随机数,无论是继续生成下一个,还是重新开始随机
  •  rnd(0)  生成最近生成的数。也就是继续生成下一个的时候会是一样的上次的,重新开始也是一样,因为 永远=第1个。
  •  rnd(1) 生成下一个数,且生成的下一个会不一样。但是,重新开始会依然从相同的第1个开始,也就是序列相同。
  • rnd 同正数的

3.4 如何每次随机都得到相同的随机序列呢?

3.4.1 使用  rnd  负数

  • 如果想每次随机都得到相同的随机序列
  • 只要在随机前加一句  rnd  负数
  • 并且 rnd  -1 和  rnd  -2 得出的随机序列还不相同
Sub TEST33()
  Rnd -2     '修改不同负数可得到可重复的不同序列的随机数
  For i = 1 To 5
    Debug.Print Rnd()
  Next
  Debug.Print "OK"
End Sub

3.4.2 一些其他的可能性

  • 配合 rnd  负数
  • 还可以加  randomize 数字(但是 只有randomize 数字 这一句无法实现这个效果的)
  • 实现随机序列的不同
Sub TEST34()
  Rnd -2     '修改不同负数可得到可重复的不同序列的随机数
  Randomize 888 '修改不同的Randomize 随机种子,随机序列也不同
  For i = 1 To 5
    Debug.Print Rnd()
  Next
  Debug.Print "OK"
End Sub

3.4.3 randomize 的意义

  • randomize 是随机种子
  • randomize 语句 默认= randomize  timer
  • 系统的时间作为默认的随机种子,即使你不写

3.6 配合 randomize  直接用 rnd 和 rnd(-1)  rnd(0)  rand(1)  参数负数,零,和正数 

Sub TEST4()
  Randomize
  For i = 1 To 3
    Debug.Print Rnd(-1)
  Next
End Sub
Sub TEST5()
  Randomize
  For i = 1 To 3
    Debug.Print Rnd(0)
  Next
End Sub
Sub TEST6()
  Randomize
  For i = 1 To 3
    Debug.Print Rnd(2)
  Next
End Sub
  • 最左边是test4的结果 (无论点不点停止后开始,永远都是相同的)
  • 第2个是test5 一直点运行的结果(rnd(1) 会取上次的,这次运行过程中会一样)
  • 第3个是test5的结果,同上句运行结果,为什么每次内的相同,每次外的不同。因为加了 randmize 每次重新运行时会重新随机随机种子
  • 第4个是test6点一次运行,点一次停止后的结果,每次都会不一样
  • 第5个是test6 点一次运行,点一次停止后的结果,每次都会不一样

       

3.7 配合 randomize  直接用 rnd 和 rnd(-1)  rnd(0)  rand(1)的总结

  • randomize  默认缺省会用时间当随机种子
  • randomize timer
  • 是一样的

  •  randomize  和 rnd(-1) 永远 生成相同的随机数,无论是继续生成下一个,还是重新开始随机。 参数-1 作用巨大
  •  randomize  和 rnd(0)  生成最近生成的数。也就是继续生成下一个的时候会是一样的上次的。重新开始也不一样,因为随机种子不同的,下次的第1个不同了!
  • 但是往下运行,还是会生成和这次结束前上1个一样的
  •  randomize  和 rnd(1) 生成下一个数,且生成的下一个会不一样。但是,重新开始因为随机种子不同,会完全一样的随机序列。
  •  randomize  和rnd 同正数的

4 总结

  • 如果想永远生成相同的随机数,就用rnd(-1) 但是这么做没意义吧?
  • 如果想每次生成的随机数,本次程序运行结束前都一样,下次计算时不一样。就用  randmize  和 rnd(0)
  • 如果想永远生成不同的随机数,无论是序列内,还是在不同的环境重新运行都不同,就用   randmize  和 rnd(1) 或 randmize 和 rnd  缺省就可以。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值