Lua math.random() 函数经常返回 0
我正在使用 Lua 进行分布和直方图的制作,在这个过程中我需要生成介于 0 和 1 之间的随机数。由于我需要生成成千上万个这样的随机数并对每个随机数的对数进行计算,所以我发现了之前使用 math.random() 函数从未遇到过的问题:这个函数生成了出乎意料的多的 0 值。由于它生成了带有 14 个小数位的数字,我期望每次调用该函数时大约有一次在 10^14 次中生成一个 0,但实际上我发现在调用 math.random() 函数 100,000 次时,会得到至多 5 或 6 个 0。这里是我制作的一个简单测试。首要问题是,由于我必须计算这些随机值的对数,因此 math.log(0) 返回 -inf,这会干扰大多数变量,如平均值和标准偏差。
这不是一个严肃的项目,我可以很容易地通过多种方法解决这个问题,甚至可以在获得 0 值时重新计算一个随机数,但我想知道这里到底出了什么问题。我在 Python 中尝试了同样的方法,没有遇到这个问题。我还发现 math.random() 不会返回小于 0.00001 的任何数字(除了 0),这让我认为这是一个舍入问题。
那么到底出了什么问题,如何获得一个更均匀分布的 [0,1) 区间的随机数生成器?感谢任何帮助!
我完全无法复制你的结果!
这是我的测试代码:
math.randomseed(os.time())
function test(n)
local k = 0
for i=1, n do
if math.random() == 0 then
k = k + 1
end
end
return k / n
end
for i=1,6 do
print(string.format("%8.4f %%", test(1e7) * 100))
end
而且结果是:
PUC Lua 5.3.5
0.0000 %
0.0000 %
0.0000 %
0.0000 %
0.0000 %
0.0000 %
LuaJIT 2.1.0-Beta3
0.0000 %
0.0000 %
0.0000 %
0.0000 %
0.0000 %
0.0000 %
作为一个简单的解决方案,我建议这样做
local function random()
local result = math.random()
return result>0 and result or random()
end
另外,只需返回 result>0 and result or 1,因为 1 永远不会被 math.random() 返回,所以如果你不介意在其中有一些 1 的话,那是另一种选择。
所以问题可能是由于Windows PRNG引起的,正如Egor Skriptunoff所指出的那样。我仍然很好奇的是为什么没有生成介于0和0.00001之间的数字。无论如何,我现在正在使用LuaJIT,问题得到了解决(无需解决措施)!谢谢大家!
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

你可以尝试删除值为0并移动范围,像这样:
local function rnd() local base = 100000 local x = (math.random(0,base+1)-1)/base if x<0 then return rnd() end return x end local function test(n) local k=0 local x math.randomseed(os.time()) for i=1,n do x = rnd() if x==0 then k=k+1 end end print("k=",k) end test(100000)如果我们将
base值降低到10,那么你就能看到一个可以接受的限制值为 0 和 1 的数量。