"interval is empty", Lua math.random isn't working for large numbers?
lua, random
Solution
This unexpected behavior (bug?) is due to how `math.random` treats the input arguments passed in Lua 5.1. From `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;
}
As you may know in C, a standard `int` can represent values `-2,147,483,648` to `2,147,483,647`. Adding `+1` to `2,147,483,647`, like in your use-case, will overflow and wrap around the value giving `-2,147,483,648`. The end result is negative since you're multiplying a positive with a negative number.
Furthermore, anything above `2,147,483,647` will fail the `luaL_argcheck` due to overflow wraparound.
There are a few ways to address this problem:
- Upgrade to Lua 5.2. That one has since fixed this issue by treating the input arguments as `lua_Number` instead.
- Switch to LuaJIT which does not have this integer overflow issue.
- Patch the Lua 5.1 source yourself with the fix and recompile.
- Modify your random range so it does not overflow.
Problem
I didn't know if this is a bug in Lua itself or if I was doing something wrong. I couldn't find anything about it anywhere. I am using Lua for Windows (Lua 5.1.4): ``` >return math.random(0, 1000000000) 1251258 ``` This returns a random integer between 0 and 10000000000, as expected. This seems to work for all other values. But if I add a single 0: ``` >return math.random(0, 10000000000) stdin:1: bad argument #2 to 'random' (interval is empty) ``` Any number higher than that does the same thing. I tried to figure out exactly how high a number has to be to cause this and found something even weirder: ``` >return math.random(0, 2147483647) -75617745 ``` If the value is 2147483647 then it gives me negative numbers. Any higher than that and it throws an error. Any lower than that and it works fine. That's `0b1111111111111111111111111111111` in binary, 31 binary digits exactly. I am not sure what that means though.