Lua math.random()经常返回0

Lua math.random()经常返回0,random,lua,Random,Lua,我正在使用Lua中的分布和直方图,我需要为其生成0和1之间的随机数。由于我正在生成成千上万个这样的随机数,并计算每一个随机数的日志,所以在使用math.random()函数之前,我从未遇到过这样一个问题:它生成了大量出人意料的零。因为它产生一个14位小数的数字,所以我希望大约每调用函数10^14次,就得到一个0,但我在调用math.random()100000次时发现最多有5到6个。我想确认一下。主要问题是,由于我必须计算这些随机值的对数,math.log(0)返回-inf,这会弄乱我的大多数变

我正在使用Lua中的分布和直方图,我需要为其生成
0
1
之间的随机数。由于我正在生成成千上万个这样的随机数,并计算每一个随机数的日志,所以在使用
math.random()
函数之前,我从未遇到过这样一个问题:它生成了大量出人意料的零。因为它产生一个14位小数的数字,所以我希望大约每调用函数10^14次,就得到一个
0
,但我在调用
math.random()
100000次时发现最多有5到6个。我想确认一下。主要问题是,由于我必须计算这些随机值的对数,
math.log(0)
返回
-inf
,这会弄乱我的大多数变量,如平均值和标准偏差

这不是一个严肃的项目,我可以用很多方法轻松地解决这个问题,甚至每次我得到一个0就计算一个新的随机数,但我想知道这里出了什么问题。我在Python中尝试了同样的方法,但没有出现这个问题。我还发现
math.random()
不会返回任何小于0.00001的数字(0除外),这让我觉得这是一个舍入问题


那么,有什么问题吗?如何为[0,1)间隔获得更均匀分布的数字生成器?感谢您的帮助!

您可以尝试删除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)
本地函数rnd()
本地基数=100000
局部x=(数学随机(0,基数+1)-1)/基数

如果x,您可以尝试删除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)
本地函数rnd()
本地基数=100000
局部x=(数学随机(0,基数+1)-1)/基数
如果席根本不能复制你的结果!
以下是我的测试代码:

math.randomseed(os.time())
功能测试(n)
局部k=0
对于i=1,n do
如果math.random()==0,则
k=k+1
结束
结束
返回k/n
结束
对于i=1,6 do
打印(字符串格式(“%8.4f%%”,测试(1e7)*100))
结束
结果是:

临市局Lua 5.3.5 LuaJIT 2.1.0-Beta3
作为一个简单的解决方法,我建议这样做

局部函数random()
局部结果=math.random()
返回结果>0和结果或随机()
结束
或者,只需返回
result>0和result或1
,因为
1
无论如何都不会由
math.random()
返回,所以如果您不介意在其中输入几个1,那是另一种选择。

我根本无法复制您的结果! 以下是我的测试代码:

math.randomseed(os.time())
功能测试(n)
局部k=0
对于i=1,n do
如果math.random()==0,则
k=k+1
结束
结束
返回k/n
结束
对于i=1,6 do
打印(字符串格式(“%8.4f%%”,测试(1e7)*100))
结束
结果是:

临市局Lua 5.3.5 LuaJIT 2.1.0-Beta3
作为一个简单的解决方法,我建议这样做

局部函数random()
局部结果=math.random()
返回结果>0和结果或随机()
结束

或者,只返回
result>0和result或1,因为
1
永远不会由
math.random()返回
无论如何,如果你不介意在那里有几个1,那是另一个选择。

所以问题可能是由于Windows PRNG,正如埃戈尔·斯克里普托诺夫指出的那样。我仍然对这样一个事实感兴趣,
0
0.00001
之间没有数字生成。无论如何,我现在正在使用LuaJIT,问题已经解决了(没有解决办法)!谢谢大家!

所以问题可能是由于Windows PRNG造成的,正如Egor Skriptunoff所指出的。我仍然对以下事实感兴趣:
0
0.00001
之间没有生成数字。不管怎样,我现在正在使用LuaJIT,问题已经解决了(没有解决办法)!谢谢大家!

我和我都没有看到这种行为……顺便说一句,你在运行什么操作系统?Windows 7.Lua 5.3.4是的,我在Windows上有相同的结果(0的频率超过2^-16)。这意味着Windows PRNG不好。请尝试使用。Lua 5.4使用自己的PRNG,而不是OS提供的PRNG。@EgorSkriptunoff LuaJIT不是也使用自己的PRNG吗?或者我只是记错了吗?@DarkWiiPlayer-是的,LuaJIT使用自己的PRNG。但是OP使用的是Lua 5.3,所以LuaJIT可能不是合适的替代品。我和我看不出来此行为…您运行的是什么操作系统?Windows 7.Lua 5.3.4是的,我在Windows上有相同的结果(频率0大于2^-16)。这意味着Windows PRNG不好。请尝试使用。Lua 5.4使用自己的PRNG,而不是OS提供的PRNG。@EgorSkriptunoff LuaJIT不是也使用自己的PRNG吗?或者我只是记错了吗?@DarkWiiPlayer-是的,LuaJIT使用自己的PRNG。但是OP使用的是Lua 5.3,所以LuaJIT可能不是合适的替代品。
  0.0000 %
  0.0000 %
  0.0000 %
  0.0000 %
  0.0000 %
  0.0000 %