我不知道这是Lua本身的错误还是我做错了什么.我无论如何都找不到任何关于它的东西.我正在使用Lua for Windows(Lua 5.1.4): return math.random(0, 1000000000)1251258 这将返回0到10000000000之间的随机整
>return math.random(0, 1000000000) 1251258
这将返回0到10000000000之间的随机整数,如预期的那样.这似乎适用于所有其他值.但如果我添加一个0:
>return math.random(0, 10000000000) stdin:1: bad argument #2 to 'random' (interval is empty)
任何高于此数字的数字都是相同的.
我试图弄清楚一个数字必须有多高才能导致这种情况发现甚至更奇怪的事情:
>return math.random(0, 2147483647) -75617745
如果值是2147483647那么它给出了负数.任何高于此值,它会抛出一个错误.任何低于它,它工作正常.
这是二进制的0b1111111111111111111111111111111,完全是31位二进制数字.我不确定这意味着什么.
这种意外行为(bug?)是由于math.random如何处理Lua 5.1中传递的输入参数.从lmathlib.c
开始:
case 2: { /* lower and upper limits */ int l = luaL_checkint(L, 1); int u = luaL_checkint(L, 2); luaL_argcheck(L, l<=u, 2, "interval is empty"); lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ break; }
正如您在C中所知,标准int可以表示值-2,147,483,648到2,147,483,647.添加1到2,147,483,647,就像在你的用例中一样,会溢出并包围给出-2,147,483,648的值.最终结果是否定的,因为您将正数乘以负数.
此外,由于溢出环绕,任何高于2,147,483,647的任何内容都将失败luaL_argcheck.
有几种方法可以解决这个问题:
>升级到Lua 5.2.那个人已经通过将输入参数视为lua_Number而修复了这个问题.>切换到没有此整数溢出问题的LuaJIT.>使用修复和重新编译自己修补Lua 5.1源代码.>修改您的随机范围,使其不会溢出.