lua随机数的问题

简介: 在看 lua 的 math.random 函数的时候发现一个问题,就是在没有重新设置随机种子的时候, random 返回的前几个随机数并不是那么特别随机,尤其当随机范围很小的时候,比如 100 左右的时候基本上都是返回 1 ,看了源码后发现内部调用是( lua5.1 源码): lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; 这其实是生成了一个 0~1 之间的小数,然后根据 math.random 的参数个数来进行操作: 无参数时直接返回这个数,当然,会进行截断。

在看 lua 的 math.random 函数的时候发现一个问题,就是在没有重新设置随机种子的时候, random 返回的前几个随机数并不是那么特别随机,尤其当随机范围很小的时候,比如 100 左右的时候基本上都是返回 1 ,看了源码后发现内部调用是( lua5.1 源码):

lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;

这其实是生成了一个 0~1 之间的小数,然后根据 math.random 的参数个数来进行操作:

无参数时直接返回这个数,当然,会进行截断。

有一个参数时,计算 floor(r*u)+1 并返回,换句话说就是用这个小数跟唯一的上限相成下取整后 +1 返回。

有两个参数时:计算 floor(r*(u-l+1))+l 并返回,意思类似。

我们知道在 C语言 里如果在 rand()之前不进行 srand() 设置随机种子,那么 rand() 返回的序列是一定的,比如我的机器上 rand() 返回的第一个值就一直是 41.所以如果不对 lua 设置种子,而直接进行随机的时候会导致在给出的唯一上限比较小时,首个值是可以确定的,举例来说

math.random(100)

这个结果基本是就是 1,因为之前没有设置过种子,根据上面的生成过程,如果我机器上 rand() 还是返回 41,那么 r 将非常的小,所以返回的第一个值将等于 1,只要当我想要随机的范围非常大时才有可能摆脱这种情况,同时你也从此会发现,在这种情况下,无论你是 math.random(99) 还是 math.random(101) 结果都将为 1,原因如上

对于这种情况,lua-user 里给出的解决方案是在随机之前设置一下种子,并抛去前三个随机数,为什么是 3 个而不是 4 个,我也不知道为什么。。。。。。

同时把什么作为种子也是一个问题,一般对于随机性要求不高的系统来说,通常可以把系统时间作为种子,于是我们可以这么写:

math.randomseed( os.time() )
math.random(); math.random(); math.random()

但是这里还有一个问题,就是 os.time() 在短时间内变化非常小,系统时间按秒来递增,一段时间内变化的只是最低几位,如果你把这段代码运行起来就会发现,如果你运行程序的时间间隔不大的时候,随机数是没有变化的,对此 lua-user 也给出了方案:

math.randomseed( tonumber(tostring(os.time()):reverse():sub(1,6)) )

意思就是这个 os.time() 的数不是按秒变化吗?那就把它反过来,这样只要秒有变动,整个数就变动非常大,后面取了前 6 位,应该是种子的变化级别到了 10的5次方后应该就非常明显了,不需要更大的种子了。

但是这里还有一个问题,正是因为他截取了前 6 位,所以经过一段比较长的时间后这里的种子有可能又开始重复了,但是基于这种情况发生的概率比较小,而且即使发生重复,整体看起来应该也不影响随机性,所以可以接受。

详情见:http://lua-users.org/wiki/MathLibraryTutorial

倾城之链 | NICE LINKS DJI Mavic Air
目录
相关文章
|
9月前
|
Rust 数据安全/隐私保护
rust每日一库 rand 生成随机数
rust每日一库 rand 生成随机数
216 0
|
算法 安全 JavaScript
聊聊程序中的随机数
聊聊程序中的随机数
283 1
|
编译器 C语言 C++
C++中rand随机数的用法
C++标准函数库提供一随机数生成器rand,返回0-RAND_MAX之间均匀分布的伪随机整数。 RAND_MAX必须至少为32767。rand()函数不接受参数,默认以1为种子(即起始值)。 随机数生成器总是以相同的种子开始,所以形成的伪随机数列也相同,失去了随机意义。(但这样便于程序调试)
Lua 函数
Lua 函数
202 0
Lua 函数
|
算法 PHP 索引
**PHP随机数算法
输出: Array( [0] => 6 [1] => 8 [2] => 13 [3] => 16 [4] => 17 [5] => 20 [6] => 21 [7] => 22 [8] => 28 [9] => 29)   ----------------------------------------- 参考: 无论是Web应用,还是WAP或者移动应用,随机数都有其用武之地。
1036 0
随机数,函数
1.随机一个1-10之间的小数
102 0

热门文章

最新文章