/* ** This function uses 'double' (instead of 'lua_Number') to ensure that ** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0' ** will keep full precision (ensuring that 'r' is always less than 1.0.) */ static int math_random(lua_State *L) { lua_Integer low, up; double r = (double)l_rand() * (1.0 / ((double)L_RANDMAX + 1.0)); switch (lua_gettop(L)) { /* check number of arguments */ case 0: { /* no arguments */ lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */ return 1; } case 1: { /* only upper limit */ low = 1; up = luaL_checkinteger(L, 1); break; } case 2: { /* lower and upper limits */ low = luaL_checkinteger(L, 1); up = luaL_checkinteger(L, 2); break; } default: return luaL_error(L, "wrong number of arguments"); } /* random integer in the interval [low, up] */ luaL_argcheck(L, low <= up, 1, "interval is empty"); luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1, "interval too large"); r *= (double)(up - low) + 1.0; lua_pushinteger(L, (lua_Integer)r + low); return 1; }
static int tshuffle (lua_State *L) { lua_Integer begin, end; checktab(L, 1, TAB_RW); begin = luaL_optinteger(L, 2, 1); end = luaL_opt(L, luaL_checkinteger, 3, check_n(L, 1)); while (end >= begin) { double f = l_rand() * (1.0/(L_RANDMAX+1.0)); lua_Integer j = begin + (lua_Integer)(f * (end-begin+1)); lua_geti(L, 1, end); lua_geti(L, 1, j); lua_seti(L, 1, end); lua_seti(L, 1, j); --end; } return 0; }
static int math_randomseed (lua_State *L) { l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1)); (void)l_rand(); /* discard first value to avoid undesirable correlations */ return 0; }