&引用;“间隔为空”;,Lua math.random不是';你不为大数字工作吗?

&引用;“间隔为空”;,Lua math.random不是';你不为大数字工作吗?,random,lua,Random,Lua,我不知道这是Lua本身的一个bug,还是我做错了什么。我在任何地方都找不到关于它的任何东西。我正在使用Lua for Windows(Lua 5.1.4): 这将返回一个介于0和1000000000之间的随机整数,如预期的那样。这似乎适用于所有其他价值观。但如果我添加一个0: >return math.random(0, 10000000000) stdin:1: bad argument #2 to 'random' (interval is empty) 任何高于这个数字的数字都会做

我不知道这是Lua本身的一个bug,还是我做错了什么。我在任何地方都找不到关于它的任何东西。我正在使用Lua for Windows(Lua 5.1.4):

这将返回一个介于0和1000000000之间的随机整数,如预期的那样。这似乎适用于所有其他价值观。但如果我添加一个0:

>return math.random(0, 10000000000)
stdin:1: bad argument #2 to 'random' (interval is empty)
任何高于这个数字的数字都会做同样的事情

我试图弄清楚一个数字到底有多高才能导致这种情况,发现了更奇怪的事情:

>return math.random(0, 2147483647)
-75617745
如果值是2147483647,那么它会给我负数。任何高于该值的值都会抛出一个错误。任何低于此值的值都可以正常工作

这是二进制的
0b1111111111111111111
,正好是31个二进制数字。我不确定这意味着什么。

这种意外行为(bug?)是由于
math.random
如何处理Lua5.1中传递的输入参数造成的。发件人:

情况2:{/*下限和上限*/
int l=luaL_checkint(l,1);
int u=luaL_checkint(L,2);

luaL_argcheck(L,L如果您需要的范围大于随机函数支持的范围(32位有符号整数或2^31,因为math.random处于C级别),但小于Lua“number”类型的范围(基于,2^52,甚至2^53),您可以尝试生成两个随机数:将第一个随机数缩放到所需的范围;将第二个随机数添加到“填补空白”。例如,假设您想要0到2^36的范围。math.random中的最大值为2^31。因此,您可以执行以下操作:

-- 2^36 = 2^31 * 2^5 so
scale = 2^5
baseRand = scale * math.random(0, 2^31)
-- baseRand is now between 0 and 2^36 but there are gaps of 2^5 in the set 
-- of possible values; fill the gaps with second random number: 
fillGap = math.random(0, 2^5)
randNum = baseRand + fillGap
只要所需的范围小于Lua解释器对Lua数字的最大值(这是一个可配置的编译时参数),这将起作用,但如果使用stock build,它是2^52,一个非常大的数字(尽管没有最大的长整数2^63大)

还要注意的是,最大的正N位整数是2^N-1(不是2^N),但上述技术可以应用于任何范围,例如,您可以使用scale=10^6,然后randNum=10^6*math.random(0,10^8)+math.random(0,10^6)

-- 2^36 = 2^31 * 2^5 so
scale = 2^5
baseRand = scale * math.random(0, 2^31)
-- baseRand is now between 0 and 2^36 but there are gaps of 2^5 in the set 
-- of possible values; fill the gaps with second random number: 
fillGap = math.random(0, 2^5)
randNum = baseRand + fillGap