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 ...
随机推荐
- Java 第18章 多态
18 章 --> 多态 继承: extends 抽象类 abstract (限制类的实例化) 抽象方法 public abstract void show(); //抽象方法只有方法的声明,没 ...
- maven nexus私服搭建,特别痛苦!!
一.下载nexu,配置环境 参考我的文章:http://www.cnblogs.com/quanyongan/archive/2013/04/24/3037589.html 二.解压并准备Nexus安 ...
- MyBatis Generator 详解 【转来纯为备忘】
版权声明:版权归博主所有,转载请带上本文链接!联系方式:abel533@gmail.com 目录(?)[+] MyBatis Generator中文文档 运行MyBatis Generator X ...
- bootstrap框架 导航条组件使用
本文记载boot 导航条组件使用方法 导航条组件 导航条是在您的应用或网站中作为导航页头的响应式基础组件.它们在移动设备上可以折叠(并且可开可关),且在视口(viewport)宽度增加时逐渐变为水平展 ...
- Mysql --分区表的管理与维护
改变一个表的分区方案只需使用alter table 加 partition_options 子句就可以了.和创建分区表时的create table语句很像 创建表 CREATE TABLE trb3 ...
- Android数据存储之SharedPreferences存储
安卓系统为应用提供了系统级的配置存储方案,它就是靠SharedPreferences接口来实现的,该接口存储的所有信息都是以名值对的形式保存,但其保存的数据类型也仅限于基本数据类型,如字符串.整形.布 ...
- WPF 自定义TextBox,可控制键盘输入内容
非原创,整理之前的代码的时候找出来的,可用,与大家分享一下! public class NumbericBoxWithZero : NumericBox { public NumbericBoxWit ...
- 解决VS2010子目录中的.cpp文件引用上一级目录的stdafx.h找不到定义的问题
Source目录 |-- stdafx.h |--Util目录 |--Util.h |--Util.cpp 现在的发现Util.cpp各种变量的定义全是红色波浪线,找不到定义,但是却能够编译过 问题就 ...
- (转)将win7电脑无线网变身WiFi热点,让手机、笔记本共享上网
将win7电脑变身WiFi热点,让手机.笔记本共享上网 功能:开启windows 7的隐藏功能:虚拟WiFi和SoftAP(即虚拟无线AP),就可以让电脑变成无线路由器,实现共享上网,节省网费和路由器 ...
- Android 客户端设计之解决方案
解决方案,是正对与需求来谈的.一个抽象的需求,需要一个较为上层抽象的解决方案来处理,这是病和药的关系.但是一个解决方案,可能会包含多个功能,每个功能都是解决方案上的一个节点.一个优秀的解决方案必然需要 ...