Lua 随机数生成问题

Lua 生成随机数需要用到两个函数:

math.randomseed(xx), math.random([n [, m]])

1. math.randomseed(n) 接收一个整数 n 作为随机序列种子。

2. math.random([n [, m]]) 有三种用法: 无参调用, 产生 (0,1) 之间的浮点随机数; 只有参数 n, 产生 1-n 之间的整数; 有两个参数 n, m, 产生 n-m 之间的随机整数

对于相同的随机种子, 生成的随即序列一定是相同的。所以程序每次运行, 赋予不同的种子很重要。很自然想到使用系统时间作为随机种子,即:

[plain] view plain copy

  1. math.randomseed(os.time())
  2. ----然后不断产生随机数
  3. for i=1, 5 do
  4. print(math.random())
  5. end

但是问题出来了, 如果程序运行时间, 你又在很短的时间内多次运行这个程序,那么你得到的随机序列会是几乎不变的。 像这样:
>lua -e "io.stdout:setvbuf ‘no‘" "test.lua"

0.71141697439497

0.060121463667714

0.067506942960906

0.8607745597705

0.60652485732597

>Exit code: 0

>lua -e "io.stdout:setvbuf ‘no‘" "test.lua"

0.71141697439497

0.060121463667714

0.067506942960906

0.8607745597705

0.60652485732597

>Exit code: 0

>lua -e "io.stdout:setvbuf ‘no‘" "test.lua"

0.7115085299234

0.38813440351573

0.6127201147496

0.59511093478195

0.9212927640614

>Exit code: 0

可以看到前两次运行的随机数都是一样的。究其原因,就是 os.time() 返回的时间是秒级的, 不够精确, 而 random() 还有个毛病就是如果 seed 很小或者seed 变化很小,产生的随机序列仍然很相似。比如:

[plain] view plain copy

  1. math.randomseed(100)
  2. print(math.random(1000))
  3. math.randomseed(102)
  4. print(math.random(1000))

两次赋予的 seed 分别是 100, 102 但是random 生成的第一个随机数却是一样的。因此“短时间内多次运行程序” 这样的需求下 os.time 还真不大好。可是又没有比 time 函数更方便的种子生成器, 怎么办呢?

可以这样:

[plain] view plain copy

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

就是把 time返回的数值字串倒过来(低位变高位), 再取高位6位。 这样, 即使 time变化很小, 但是因为低位变了高位, 种子数值变化却很大,就可以使伪随机序列生成的更好一些

参考文章:http://lua-users.org/wiki/MathLibraryTutorial

数学库源码: http://www.lua.org/source/5.1/lmathlib.c.html

原文地址:https://www.cnblogs.com/aibox222/p/9050754.html

时间: 2024-11-10 08:30:05

Lua 随机数生成问题的相关文章

Redis源码中看伪随机数生成算法

导读 --------------------------------------------------------------------------------------------------------------------------------------------------------------         Redis源码中有一个rand.c的源文件,很明显这是一个和(伪)随机数有关的文件.细看该文件代码只有寥寥50行,不过涉及到的算法原理却不简单,读起来虽然有些晦

cocos2dx lua中异步加载网络图片,可用于显示微信头像

最近在做一个棋牌项目,脚本语言用的lua,登录需要使用微信登录,用户头像用微信账户的头像,微信接口返回的头像是一个url,那么遇到的一个问题就是如何在lua中异步加载这个头像,先在引擎源码里找了下可能会提供这个功能的地方,发现好像没有提供类似功能,那么只能自己动手写.所以我在ImageView这个类里面添加了一个成员方法,其实可以不写在ImageView里,而且我觉得非必需情况下还是不要修改引擎源码的好,因为如果源码改动比较多的话,将来引擎版本升级会比较麻烦.我写在ImageView里纯粹是想偷

Lua 第一天

今天开始学习Lua语言,感觉Lua非常便捷.我用的编译器是SciTE,很不错. 举例一:无需引用,内置输出语句   print() print(6)   --> 6 print(type(6))  -->   number 举例二:对数字字符串进行数字化处理 print("2"+3 )  -->5 举例三:..连接俩个字符串,#返回字符串长度 举例四:print()输出函数,可以有多个输出值 a = 1,b =2,c = a+b    print(a,b,c,a,b,

lua协程一则报错解决“attempt to yield across metamethod/C-call boundary”

问题 attempt to yield across metamethod/C-call boundary 需求跟如下帖子中描述一致: http://bbs.chinaunix.net/forum.php?mod=viewthread&action=printable&tid=4065715 模拟一个场景,在C中创建出coroutine来执行Lua脚本,并且提供C API给Lua使用,当某些操作可能会阻塞时(如网络I/O),C函数中执行yield将协程切换出去,然后未来的某个时刻,如果条件

lua闭合函数

function count( ... ) local i = 0 return function( ... ) i = i+ 1 return i end end local func = count(...) print(func()) print(func()) print(func()) 结果如下: 1 2 3 [Finished in 0.1s] lua 闭合函数:一个函数加上该函数所需访问的所有“非局部变量”. 如上所示:count()函数返回了另一个函数,而这个函数使用了count

Mac下Lua Sublime Text2 开发环境搭建

1.安装Lua编译器 下载Lua, http://www.lua.org/: 解压后,cd进入该文件夹src目录下 在当前文件夹执行make macosx   然后回车 cd 到上一目录,执行sudo make install 完成之后执行lua -v 可以看到:Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio 2.安装Sublime Text2 1.下载http://sublime-text-2.cn.uptodown.com后打开: {

Nginx+Lua 积累

Nginx+Lua 积累 1.解析16进制编码的中文参数 复制代码 local encodeStr = "%E6%B0%94" local decodeStr = ""; for i = 2, #encodeStr - 1, 3 do local num = encodeStr:sub(i, i + 1); num = tonumber(num, 16); decodeStr = decodeStr .. string.char(num); end ngx.say(

nginx与Lua执行顺序

Nginx顺序 Nginx 处理每一个用户请求时,都是按照若干个不同阶段(phase)依次处理的,而不是根据配置文件上的顺序. Nginx 处理请求的过程一共划分为 11 个阶段,按照执行顺序依次是 post-read.server-rewrite.find-config.rewrite.post-rewrite. preaccess.access.post-access.try-files.content.log. post-read: 读取请求内容阶段 Nginx读取并解析完请求头之后就立即

在 Lua 里 使用 Cocos Studio 导出的 .csb 文件

1. 加载 节点到场景 第一种方法 local scene = cc.CSLoader:createNode("scene.csb") self:addChild(scene) 第二种方法 local scene = cc.uiloader:load("MainScene.csb"):addTo(self) 2.强转精灵类型 local sprite = tolua.cast(object,"cc.Sprite") CocoStudio 做的里面