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 的参数个数来进行操作:
无参数时直接返回这个数,当然,会进行截断。
有一个参数时,计算 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
lua随机数的问题的更多相关文章
- lua 随机数 math.random()和math.randomseed()用法
用法一: 不给范围,就随机算一个0~1之间的小数: 用法二:给一个参数,就取1~n之间的随机数 用法三:给两个参数,就取m~n之间的随机数 math.randomseed()用法: 由于C中 ...
- lua随机数函数
function rnd(max) --lua的第1次random数不靠谱,取第3次的靠谱 local ret=0 math.randomseed(os.time()) for i=1,3 d ...
- Redis进阶实践之十九 Redis如何使用lua脚本
一.引言 redis学了一段时间了,基本的东西都没问题了.从今天开始讲写一些redis和lua脚本的相关的东西,lua这个脚本是一个好东西,可以运行在任何平台上,也可以嵌入 ...
- cocos2d-x学习笔记
转自:http://blog.csdn.net/we000636/article/details/8263503 接受触屏事件的优先级是值越小,响应触屏事件的优先级越高 Z值越大,越外面 JNI:允许 ...
- 关于LUA中的随机数问题
也许很多人会奇怪为什么使用LUA的时候,第一个随机数总是固定,而且常常是最小的那个值,下面我就简要的说明一下吧,说得不好,还请谅解.我现在使用的4.0版本的LUA,看的代码是5.0的,呵呵 LUA4. ...
- Lua生成比较理想的随机数的方法
lua需要生成随机数的需求也是很常见的,为了生成看起来更随机的数字,我们需要注意以下几点 我们也需要给随机数设置随机数种子:math.randomseed(xx) lua对随机数种子也是有一定要求的: ...
- lua中的随机数
Lua 生成随机数需要用到两个函数:math.randomseed(xx), math.random([n [, m]]) 1. math.randomseed(n) 接收一个整数 n 作为随机序列种 ...
- lua连续随机数
号外:惭愧,工作后几乎没有写博客了,其实是有时间的(每周单休),只是厌烦对着屏幕了,还有懒. 现在老板换人了,时间会多点,估计正常就每周双休了,决定还是每周写两篇(不一定是love2d), 写不出就翻 ...
- lua 中随机数产生
需要用到两个函数: (1)math.randomseed(N): 接收一个整数N作为随机序列种子 (2)math.random([n, [m]]): 这个函数有三种用法,分别是不跟参数,此时产生(0 ...
随机推荐
- Lessons Learned 1(敏捷项目中的变更影响分析)
问题/现象: 业务信息流转的某些环节,会向相关人员发送通知邮件,邮件中附带有链接,供相关人员进入察看或处理业务.客户要求邮件中的链接,需要进行限制,只有特定人员才能进入处理或察看.总管想了想,应道没问 ...
- Linux的phpstudy mysql登录
使用绝对路径登录 /phpStudy/mysql/bin/mysql -uroot -p; 设置远程登录密码 GRANT ALL PRIVILEGES ON *.* TO 'itoffice'@'%' ...
- php压缩文件
$filename = './qrcode.zip'; // 最终生成的文件名(含路径) //生成文件 $zip = new ZipArchive (); // 使用本类,linux需开启zlib,w ...
- Mac OS X 访问 Windows 共享文件夹
Mac OS X 访问 Windows 共享文件夹 mac没有网络邻居,但可以使用finder访问局域网中windows共享的文件 1.点击 Finder 前往菜单中的「前往服务器」(或快捷键 com ...
- SVN修改用户名与密码
由于在svn的界面中并没有为我们提供直接更换用户名密码的地方,所以一旦我们需要更换用户名的就需要自己想一些办法. 解决方案如下: 在Eclipse使用SVN的过程中大多数人往往习惯把访问SVN的用户名 ...
- Windows环境下使用Clover四叶草引导双硬盘安装OSX 10.11.5原版镜像
作为一个穷逼大学生,想搞iOS开发 买不起Mac只能鼓捣鼓捣黑苹果啦........ 之前我的电脑通过变色龙引导的方式装了个OSX10.10和win8.1双系统,因为自学的是Swift语言之前装的OS ...
- being词典案例分析
一.调研评测: 1.软件bug: 1.输入空格分号回车之后并不给用户报错,说明他的异常处理机制有问题. 2.对于中文的很多口头语和方言,并不能给出翻译或者说,也并没有给出网络搜索后的结果. 3.添加生 ...
- ubuntu安装packet提示重复冲突问题
今天装个zip出现: dpkg: error processing archive /var/cache/apt/archives/libc6-dev-i386_2.19-0ubuntu6.5_amd ...
- Eclipse配置PHP及自动提示功能
Eclipse是一个开发工具,具有强大的插件功能,虽然用于Java理所当然,但为PHP所用,也为尝不可.虽然我一直用的是notepad,但发现开发工具也可以省去一些不必要的记忆. 言归正传,下面就来实 ...
- 3.一起来学hibernate之配置文件2
之前的映射文件配置都是简单的.基础的配置,只涉及到单个javabean,对于单个javabean的增删改查都能很好的.简单的去完成. 但是知道简单配置远远不够,并不能完成很多复杂的情况,比如对象与对象 ...