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 ...
随机推荐
- ajax基础一
AJAX AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现有标准的新方法. AJA ...
- windows下nginx的启动关闭
Windows下Nginx的启动.停止等命令 在Windows下使用Nginx,我们需要掌握一些基本的操作命令,比如:启动.停止Nginx服务,重新载入Nginx等,下面我就进行一些简单的介绍. .启 ...
- MIUI系统安全中心之自启动管理解密
迄今为止,Android系统的手机已经在整个手机市场中占有很大的比重.其中小米手机更是因为它的性价比和销售模式普遍的出现在了人们的日长生活中. 废话不多说,进入正题.作为一个Android的开发者,避 ...
- u3d avatar部件的理解
u3d中带动画的fbx文件导入的时候,就会显示一个avatar组件,这个到底干嘛的一直没能很好的理解,翻看网上的介绍,基本都是告诉你,设置humanoid类型动画时,拖拉过去之类,但是这玩意到底存储了 ...
- Mac OS 系统工具使用
1. 截屏的处理 Command + Shift + 4
- Memcached & Redis使用
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memcached ...
- 用canvas制作酷炫射击游戏--part2
今天这一部分主要讲游戏的实现原理与游戏循环的代码实现. 先说原理,大家都看过动画吧.在我看来,游戏就是玩家能人为控制动画剧情发展方向的动画.所以,我们的游戏引擎其实说白了就是个动画引擎再加上鼠标事件. ...
- HTML5实战1
第一章 1.搭建环境,wamp 2.检查浏览器是否支持html5 ,是否支持新标签<canvas></canvas> 3.简单高效,少用id,多用标签. 4.使用css3美化样 ...
- 第一次自己写jquery图片延迟加载插件,不通用,但修改一下还是可以使用到很多页面上的
不断修改完善中…… /*! * jquery.lazyoading.js *自定义的页面图片延迟加载插件,比网上的jquery.lazyload简单,也更适合自己的网站 *使用方法: 把img 的cl ...
- 《理解 ES6》阅读整理:函数(Functions)(五)Name Property
名字属性(The name Property) 在JavaScript中识别函数是有挑战性的,因为你可以使用各种方式来定义一个函数.匿名函数表达式的流行使用导致函数调试困难,在栈信息中难以找出函数名. ...