18e3e3a7aSWarner Losh /* 2*0495ed39SKyle Evans ** $Id: lmathlib.c $ 38e3e3a7aSWarner Losh ** Standard mathematical library 48e3e3a7aSWarner Losh ** See Copyright Notice in lua.h 58e3e3a7aSWarner Losh */ 68e3e3a7aSWarner Losh 78e3e3a7aSWarner Losh #define lmathlib_c 88e3e3a7aSWarner Losh #define LUA_LIB 98e3e3a7aSWarner Losh 108e3e3a7aSWarner Losh #include "lprefix.h" 118e3e3a7aSWarner Losh 128e3e3a7aSWarner Losh 13*0495ed39SKyle Evans #include <float.h> 14*0495ed39SKyle Evans #include <limits.h> 158e3e3a7aSWarner Losh #include <math.h> 16*0495ed39SKyle Evans #include <stdlib.h> 17*0495ed39SKyle Evans #include <time.h> 188e3e3a7aSWarner Losh 198e3e3a7aSWarner Losh #include "lua.h" 208e3e3a7aSWarner Losh 218e3e3a7aSWarner Losh #include "lauxlib.h" 228e3e3a7aSWarner Losh #include "lualib.h" 238e3e3a7aSWarner Losh 248e3e3a7aSWarner Losh 258e3e3a7aSWarner Losh #undef PI 268e3e3a7aSWarner Losh #define PI (l_mathop(3.141592653589793238462643383279502884)) 278e3e3a7aSWarner Losh 288e3e3a7aSWarner Losh 298e3e3a7aSWarner Losh static int math_abs (lua_State *L) { 308e3e3a7aSWarner Losh if (lua_isinteger(L, 1)) { 318e3e3a7aSWarner Losh lua_Integer n = lua_tointeger(L, 1); 328e3e3a7aSWarner Losh if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n); 338e3e3a7aSWarner Losh lua_pushinteger(L, n); 348e3e3a7aSWarner Losh } 358e3e3a7aSWarner Losh else 368e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); 378e3e3a7aSWarner Losh return 1; 388e3e3a7aSWarner Losh } 398e3e3a7aSWarner Losh 408e3e3a7aSWarner Losh static int math_sin (lua_State *L) { 418e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); 428e3e3a7aSWarner Losh return 1; 438e3e3a7aSWarner Losh } 448e3e3a7aSWarner Losh 458e3e3a7aSWarner Losh static int math_cos (lua_State *L) { 468e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); 478e3e3a7aSWarner Losh return 1; 488e3e3a7aSWarner Losh } 498e3e3a7aSWarner Losh 508e3e3a7aSWarner Losh static int math_tan (lua_State *L) { 518e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); 528e3e3a7aSWarner Losh return 1; 538e3e3a7aSWarner Losh } 548e3e3a7aSWarner Losh 558e3e3a7aSWarner Losh static int math_asin (lua_State *L) { 568e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); 578e3e3a7aSWarner Losh return 1; 588e3e3a7aSWarner Losh } 598e3e3a7aSWarner Losh 608e3e3a7aSWarner Losh static int math_acos (lua_State *L) { 618e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); 628e3e3a7aSWarner Losh return 1; 638e3e3a7aSWarner Losh } 648e3e3a7aSWarner Losh 658e3e3a7aSWarner Losh static int math_atan (lua_State *L) { 668e3e3a7aSWarner Losh lua_Number y = luaL_checknumber(L, 1); 678e3e3a7aSWarner Losh lua_Number x = luaL_optnumber(L, 2, 1); 688e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(atan2)(y, x)); 698e3e3a7aSWarner Losh return 1; 708e3e3a7aSWarner Losh } 718e3e3a7aSWarner Losh 728e3e3a7aSWarner Losh 738e3e3a7aSWarner Losh static int math_toint (lua_State *L) { 748e3e3a7aSWarner Losh int valid; 758e3e3a7aSWarner Losh lua_Integer n = lua_tointegerx(L, 1, &valid); 768e3e3a7aSWarner Losh if (valid) 778e3e3a7aSWarner Losh lua_pushinteger(L, n); 788e3e3a7aSWarner Losh else { 798e3e3a7aSWarner Losh luaL_checkany(L, 1); 80*0495ed39SKyle Evans luaL_pushfail(L); /* value is not convertible to integer */ 818e3e3a7aSWarner Losh } 828e3e3a7aSWarner Losh return 1; 838e3e3a7aSWarner Losh } 848e3e3a7aSWarner Losh 858e3e3a7aSWarner Losh 868e3e3a7aSWarner Losh static void pushnumint (lua_State *L, lua_Number d) { 878e3e3a7aSWarner Losh lua_Integer n; 888e3e3a7aSWarner Losh if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */ 898e3e3a7aSWarner Losh lua_pushinteger(L, n); /* result is integer */ 908e3e3a7aSWarner Losh else 918e3e3a7aSWarner Losh lua_pushnumber(L, d); /* result is float */ 928e3e3a7aSWarner Losh } 938e3e3a7aSWarner Losh 948e3e3a7aSWarner Losh 958e3e3a7aSWarner Losh static int math_floor (lua_State *L) { 968e3e3a7aSWarner Losh if (lua_isinteger(L, 1)) 978e3e3a7aSWarner Losh lua_settop(L, 1); /* integer is its own floor */ 988e3e3a7aSWarner Losh else { 998e3e3a7aSWarner Losh lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1)); 1008e3e3a7aSWarner Losh pushnumint(L, d); 1018e3e3a7aSWarner Losh } 1028e3e3a7aSWarner Losh return 1; 1038e3e3a7aSWarner Losh } 1048e3e3a7aSWarner Losh 1058e3e3a7aSWarner Losh 1068e3e3a7aSWarner Losh static int math_ceil (lua_State *L) { 1078e3e3a7aSWarner Losh if (lua_isinteger(L, 1)) 1088e3e3a7aSWarner Losh lua_settop(L, 1); /* integer is its own ceil */ 1098e3e3a7aSWarner Losh else { 1108e3e3a7aSWarner Losh lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1)); 1118e3e3a7aSWarner Losh pushnumint(L, d); 1128e3e3a7aSWarner Losh } 1138e3e3a7aSWarner Losh return 1; 1148e3e3a7aSWarner Losh } 1158e3e3a7aSWarner Losh 1168e3e3a7aSWarner Losh 1178e3e3a7aSWarner Losh static int math_fmod (lua_State *L) { 1188e3e3a7aSWarner Losh if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { 1198e3e3a7aSWarner Losh lua_Integer d = lua_tointeger(L, 2); 1208e3e3a7aSWarner Losh if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */ 1218e3e3a7aSWarner Losh luaL_argcheck(L, d != 0, 2, "zero"); 1228e3e3a7aSWarner Losh lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */ 1238e3e3a7aSWarner Losh } 1248e3e3a7aSWarner Losh else 1258e3e3a7aSWarner Losh lua_pushinteger(L, lua_tointeger(L, 1) % d); 1268e3e3a7aSWarner Losh } 1278e3e3a7aSWarner Losh else 1288e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), 1298e3e3a7aSWarner Losh luaL_checknumber(L, 2))); 1308e3e3a7aSWarner Losh return 1; 1318e3e3a7aSWarner Losh } 1328e3e3a7aSWarner Losh 1338e3e3a7aSWarner Losh 1348e3e3a7aSWarner Losh /* 1358e3e3a7aSWarner Losh ** next function does not use 'modf', avoiding problems with 'double*' 1368e3e3a7aSWarner Losh ** (which is not compatible with 'float*') when lua_Number is not 1378e3e3a7aSWarner Losh ** 'double'. 1388e3e3a7aSWarner Losh */ 1398e3e3a7aSWarner Losh static int math_modf (lua_State *L) { 1408e3e3a7aSWarner Losh if (lua_isinteger(L ,1)) { 1418e3e3a7aSWarner Losh lua_settop(L, 1); /* number is its own integer part */ 1428e3e3a7aSWarner Losh lua_pushnumber(L, 0); /* no fractional part */ 1438e3e3a7aSWarner Losh } 1448e3e3a7aSWarner Losh else { 1458e3e3a7aSWarner Losh lua_Number n = luaL_checknumber(L, 1); 1468e3e3a7aSWarner Losh /* integer part (rounds toward zero) */ 1478e3e3a7aSWarner Losh lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n); 1488e3e3a7aSWarner Losh pushnumint(L, ip); 1498e3e3a7aSWarner Losh /* fractional part (test needed for inf/-inf) */ 1508e3e3a7aSWarner Losh lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); 1518e3e3a7aSWarner Losh } 1528e3e3a7aSWarner Losh return 2; 1538e3e3a7aSWarner Losh } 1548e3e3a7aSWarner Losh 1558e3e3a7aSWarner Losh 1568e3e3a7aSWarner Losh static int math_sqrt (lua_State *L) { 1578e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); 1588e3e3a7aSWarner Losh return 1; 1598e3e3a7aSWarner Losh } 1608e3e3a7aSWarner Losh 1618e3e3a7aSWarner Losh 1628e3e3a7aSWarner Losh static int math_ult (lua_State *L) { 1638e3e3a7aSWarner Losh lua_Integer a = luaL_checkinteger(L, 1); 1648e3e3a7aSWarner Losh lua_Integer b = luaL_checkinteger(L, 2); 1658e3e3a7aSWarner Losh lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b); 1668e3e3a7aSWarner Losh return 1; 1678e3e3a7aSWarner Losh } 1688e3e3a7aSWarner Losh 1698e3e3a7aSWarner Losh static int math_log (lua_State *L) { 1708e3e3a7aSWarner Losh lua_Number x = luaL_checknumber(L, 1); 1718e3e3a7aSWarner Losh lua_Number res; 1728e3e3a7aSWarner Losh if (lua_isnoneornil(L, 2)) 1738e3e3a7aSWarner Losh res = l_mathop(log)(x); 1748e3e3a7aSWarner Losh else { 1758e3e3a7aSWarner Losh lua_Number base = luaL_checknumber(L, 2); 1768e3e3a7aSWarner Losh #if !defined(LUA_USE_C89) 1778e3e3a7aSWarner Losh if (base == l_mathop(2.0)) 1788e3e3a7aSWarner Losh res = l_mathop(log2)(x); else 1798e3e3a7aSWarner Losh #endif 1808e3e3a7aSWarner Losh if (base == l_mathop(10.0)) 1818e3e3a7aSWarner Losh res = l_mathop(log10)(x); 1828e3e3a7aSWarner Losh else 1838e3e3a7aSWarner Losh res = l_mathop(log)(x)/l_mathop(log)(base); 1848e3e3a7aSWarner Losh } 1858e3e3a7aSWarner Losh lua_pushnumber(L, res); 1868e3e3a7aSWarner Losh return 1; 1878e3e3a7aSWarner Losh } 1888e3e3a7aSWarner Losh 1898e3e3a7aSWarner Losh static int math_exp (lua_State *L) { 1908e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); 1918e3e3a7aSWarner Losh return 1; 1928e3e3a7aSWarner Losh } 1938e3e3a7aSWarner Losh 1948e3e3a7aSWarner Losh static int math_deg (lua_State *L) { 1958e3e3a7aSWarner Losh lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI)); 1968e3e3a7aSWarner Losh return 1; 1978e3e3a7aSWarner Losh } 1988e3e3a7aSWarner Losh 1998e3e3a7aSWarner Losh static int math_rad (lua_State *L) { 2008e3e3a7aSWarner Losh lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0))); 2018e3e3a7aSWarner Losh return 1; 2028e3e3a7aSWarner Losh } 2038e3e3a7aSWarner Losh 2048e3e3a7aSWarner Losh 2058e3e3a7aSWarner Losh static int math_min (lua_State *L) { 2068e3e3a7aSWarner Losh int n = lua_gettop(L); /* number of arguments */ 2078e3e3a7aSWarner Losh int imin = 1; /* index of current minimum value */ 2088e3e3a7aSWarner Losh int i; 2098e3e3a7aSWarner Losh luaL_argcheck(L, n >= 1, 1, "value expected"); 2108e3e3a7aSWarner Losh for (i = 2; i <= n; i++) { 2118e3e3a7aSWarner Losh if (lua_compare(L, i, imin, LUA_OPLT)) 2128e3e3a7aSWarner Losh imin = i; 2138e3e3a7aSWarner Losh } 2148e3e3a7aSWarner Losh lua_pushvalue(L, imin); 2158e3e3a7aSWarner Losh return 1; 2168e3e3a7aSWarner Losh } 2178e3e3a7aSWarner Losh 2188e3e3a7aSWarner Losh 2198e3e3a7aSWarner Losh static int math_max (lua_State *L) { 2208e3e3a7aSWarner Losh int n = lua_gettop(L); /* number of arguments */ 2218e3e3a7aSWarner Losh int imax = 1; /* index of current maximum value */ 2228e3e3a7aSWarner Losh int i; 2238e3e3a7aSWarner Losh luaL_argcheck(L, n >= 1, 1, "value expected"); 2248e3e3a7aSWarner Losh for (i = 2; i <= n; i++) { 2258e3e3a7aSWarner Losh if (lua_compare(L, imax, i, LUA_OPLT)) 2268e3e3a7aSWarner Losh imax = i; 2278e3e3a7aSWarner Losh } 2288e3e3a7aSWarner Losh lua_pushvalue(L, imax); 2298e3e3a7aSWarner Losh return 1; 2308e3e3a7aSWarner Losh } 2318e3e3a7aSWarner Losh 232*0495ed39SKyle Evans 233*0495ed39SKyle Evans static int math_type (lua_State *L) { 234*0495ed39SKyle Evans if (lua_type(L, 1) == LUA_TNUMBER) 235*0495ed39SKyle Evans lua_pushstring(L, (lua_isinteger(L, 1)) ? "integer" : "float"); 236*0495ed39SKyle Evans else { 237*0495ed39SKyle Evans luaL_checkany(L, 1); 238*0495ed39SKyle Evans luaL_pushfail(L); 239*0495ed39SKyle Evans } 240*0495ed39SKyle Evans return 1; 241*0495ed39SKyle Evans } 242*0495ed39SKyle Evans 243*0495ed39SKyle Evans 244*0495ed39SKyle Evans 2458e3e3a7aSWarner Losh /* 246*0495ed39SKyle Evans ** {================================================================== 247*0495ed39SKyle Evans ** Pseudo-Random Number Generator based on 'xoshiro256**'. 248*0495ed39SKyle Evans ** =================================================================== 2498e3e3a7aSWarner Losh */ 250*0495ed39SKyle Evans 251*0495ed39SKyle Evans /* number of binary digits in the mantissa of a float */ 252*0495ed39SKyle Evans #define FIGS l_floatatt(MANT_DIG) 253*0495ed39SKyle Evans 254*0495ed39SKyle Evans #if FIGS > 64 255*0495ed39SKyle Evans /* there are only 64 random bits; use them all */ 256*0495ed39SKyle Evans #undef FIGS 257*0495ed39SKyle Evans #define FIGS 64 258*0495ed39SKyle Evans #endif 259*0495ed39SKyle Evans 260*0495ed39SKyle Evans 261*0495ed39SKyle Evans /* 262*0495ed39SKyle Evans ** LUA_RAND32 forces the use of 32-bit integers in the implementation 263*0495ed39SKyle Evans ** of the PRN generator (mainly for testing). 264*0495ed39SKyle Evans */ 265*0495ed39SKyle Evans #if !defined(LUA_RAND32) && !defined(Rand64) 266*0495ed39SKyle Evans 267*0495ed39SKyle Evans /* try to find an integer type with at least 64 bits */ 268*0495ed39SKyle Evans 269*0495ed39SKyle Evans #if (ULONG_MAX >> 31 >> 31) >= 3 270*0495ed39SKyle Evans 271*0495ed39SKyle Evans /* 'long' has at least 64 bits */ 272*0495ed39SKyle Evans #define Rand64 unsigned long 273*0495ed39SKyle Evans 274*0495ed39SKyle Evans #elif !defined(LUA_USE_C89) && defined(LLONG_MAX) 275*0495ed39SKyle Evans 276*0495ed39SKyle Evans /* there is a 'long long' type (which must have at least 64 bits) */ 277*0495ed39SKyle Evans #define Rand64 unsigned long long 278*0495ed39SKyle Evans 279*0495ed39SKyle Evans #elif (LUA_MAXUNSIGNED >> 31 >> 31) >= 3 280*0495ed39SKyle Evans 281*0495ed39SKyle Evans /* 'lua_Integer' has at least 64 bits */ 282*0495ed39SKyle Evans #define Rand64 lua_Unsigned 283*0495ed39SKyle Evans 284*0495ed39SKyle Evans #endif 285*0495ed39SKyle Evans 286*0495ed39SKyle Evans #endif 287*0495ed39SKyle Evans 288*0495ed39SKyle Evans 289*0495ed39SKyle Evans #if defined(Rand64) /* { */ 290*0495ed39SKyle Evans 291*0495ed39SKyle Evans /* 292*0495ed39SKyle Evans ** Standard implementation, using 64-bit integers. 293*0495ed39SKyle Evans ** If 'Rand64' has more than 64 bits, the extra bits do not interfere 294*0495ed39SKyle Evans ** with the 64 initial bits, except in a right shift. Moreover, the 295*0495ed39SKyle Evans ** final result has to discard the extra bits. 296*0495ed39SKyle Evans */ 297*0495ed39SKyle Evans 298*0495ed39SKyle Evans /* avoid using extra bits when needed */ 299*0495ed39SKyle Evans #define trim64(x) ((x) & 0xffffffffffffffffu) 300*0495ed39SKyle Evans 301*0495ed39SKyle Evans 302*0495ed39SKyle Evans /* rotate left 'x' by 'n' bits */ 303*0495ed39SKyle Evans static Rand64 rotl (Rand64 x, int n) { 304*0495ed39SKyle Evans return (x << n) | (trim64(x) >> (64 - n)); 305*0495ed39SKyle Evans } 306*0495ed39SKyle Evans 307*0495ed39SKyle Evans static Rand64 nextrand (Rand64 *state) { 308*0495ed39SKyle Evans Rand64 state0 = state[0]; 309*0495ed39SKyle Evans Rand64 state1 = state[1]; 310*0495ed39SKyle Evans Rand64 state2 = state[2] ^ state0; 311*0495ed39SKyle Evans Rand64 state3 = state[3] ^ state1; 312*0495ed39SKyle Evans Rand64 res = rotl(state1 * 5, 7) * 9; 313*0495ed39SKyle Evans state[0] = state0 ^ state3; 314*0495ed39SKyle Evans state[1] = state1 ^ state2; 315*0495ed39SKyle Evans state[2] = state2 ^ (state1 << 17); 316*0495ed39SKyle Evans state[3] = rotl(state3, 45); 317*0495ed39SKyle Evans return res; 318*0495ed39SKyle Evans } 319*0495ed39SKyle Evans 320*0495ed39SKyle Evans 321*0495ed39SKyle Evans /* must take care to not shift stuff by more than 63 slots */ 322*0495ed39SKyle Evans 323*0495ed39SKyle Evans 324*0495ed39SKyle Evans /* 325*0495ed39SKyle Evans ** Convert bits from a random integer into a float in the 326*0495ed39SKyle Evans ** interval [0,1), getting the higher FIG bits from the 327*0495ed39SKyle Evans ** random unsigned integer and converting that to a float. 328*0495ed39SKyle Evans */ 329*0495ed39SKyle Evans 330*0495ed39SKyle Evans /* must throw out the extra (64 - FIGS) bits */ 331*0495ed39SKyle Evans #define shift64_FIG (64 - FIGS) 332*0495ed39SKyle Evans 333*0495ed39SKyle Evans /* to scale to [0, 1), multiply by scaleFIG = 2^(-FIGS) */ 334*0495ed39SKyle Evans #define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1))) 335*0495ed39SKyle Evans 336*0495ed39SKyle Evans static lua_Number I2d (Rand64 x) { 337*0495ed39SKyle Evans return (lua_Number)(trim64(x) >> shift64_FIG) * scaleFIG; 338*0495ed39SKyle Evans } 339*0495ed39SKyle Evans 340*0495ed39SKyle Evans /* convert a 'Rand64' to a 'lua_Unsigned' */ 341*0495ed39SKyle Evans #define I2UInt(x) ((lua_Unsigned)trim64(x)) 342*0495ed39SKyle Evans 343*0495ed39SKyle Evans /* convert a 'lua_Unsigned' to a 'Rand64' */ 344*0495ed39SKyle Evans #define Int2I(x) ((Rand64)(x)) 345*0495ed39SKyle Evans 346*0495ed39SKyle Evans 347*0495ed39SKyle Evans #else /* no 'Rand64' }{ */ 348*0495ed39SKyle Evans 349*0495ed39SKyle Evans /* get an integer with at least 32 bits */ 350*0495ed39SKyle Evans #if LUAI_IS32INT 351*0495ed39SKyle Evans typedef unsigned int lu_int32; 352*0495ed39SKyle Evans #else 353*0495ed39SKyle Evans typedef unsigned long lu_int32; 354*0495ed39SKyle Evans #endif 355*0495ed39SKyle Evans 356*0495ed39SKyle Evans 357*0495ed39SKyle Evans /* 358*0495ed39SKyle Evans ** Use two 32-bit integers to represent a 64-bit quantity. 359*0495ed39SKyle Evans */ 360*0495ed39SKyle Evans typedef struct Rand64 { 361*0495ed39SKyle Evans lu_int32 h; /* higher half */ 362*0495ed39SKyle Evans lu_int32 l; /* lower half */ 363*0495ed39SKyle Evans } Rand64; 364*0495ed39SKyle Evans 365*0495ed39SKyle Evans 366*0495ed39SKyle Evans /* 367*0495ed39SKyle Evans ** If 'lu_int32' has more than 32 bits, the extra bits do not interfere 368*0495ed39SKyle Evans ** with the 32 initial bits, except in a right shift and comparisons. 369*0495ed39SKyle Evans ** Moreover, the final result has to discard the extra bits. 370*0495ed39SKyle Evans */ 371*0495ed39SKyle Evans 372*0495ed39SKyle Evans /* avoid using extra bits when needed */ 373*0495ed39SKyle Evans #define trim32(x) ((x) & 0xffffffffu) 374*0495ed39SKyle Evans 375*0495ed39SKyle Evans 376*0495ed39SKyle Evans /* 377*0495ed39SKyle Evans ** basic operations on 'Rand64' values 378*0495ed39SKyle Evans */ 379*0495ed39SKyle Evans 380*0495ed39SKyle Evans /* build a new Rand64 value */ 381*0495ed39SKyle Evans static Rand64 packI (lu_int32 h, lu_int32 l) { 382*0495ed39SKyle Evans Rand64 result; 383*0495ed39SKyle Evans result.h = h; 384*0495ed39SKyle Evans result.l = l; 385*0495ed39SKyle Evans return result; 386*0495ed39SKyle Evans } 387*0495ed39SKyle Evans 388*0495ed39SKyle Evans /* return i << n */ 389*0495ed39SKyle Evans static Rand64 Ishl (Rand64 i, int n) { 390*0495ed39SKyle Evans lua_assert(n > 0 && n < 32); 391*0495ed39SKyle Evans return packI((i.h << n) | (trim32(i.l) >> (32 - n)), i.l << n); 392*0495ed39SKyle Evans } 393*0495ed39SKyle Evans 394*0495ed39SKyle Evans /* i1 ^= i2 */ 395*0495ed39SKyle Evans static void Ixor (Rand64 *i1, Rand64 i2) { 396*0495ed39SKyle Evans i1->h ^= i2.h; 397*0495ed39SKyle Evans i1->l ^= i2.l; 398*0495ed39SKyle Evans } 399*0495ed39SKyle Evans 400*0495ed39SKyle Evans /* return i1 + i2 */ 401*0495ed39SKyle Evans static Rand64 Iadd (Rand64 i1, Rand64 i2) { 402*0495ed39SKyle Evans Rand64 result = packI(i1.h + i2.h, i1.l + i2.l); 403*0495ed39SKyle Evans if (trim32(result.l) < trim32(i1.l)) /* carry? */ 404*0495ed39SKyle Evans result.h++; 405*0495ed39SKyle Evans return result; 406*0495ed39SKyle Evans } 407*0495ed39SKyle Evans 408*0495ed39SKyle Evans /* return i * 5 */ 409*0495ed39SKyle Evans static Rand64 times5 (Rand64 i) { 410*0495ed39SKyle Evans return Iadd(Ishl(i, 2), i); /* i * 5 == (i << 2) + i */ 411*0495ed39SKyle Evans } 412*0495ed39SKyle Evans 413*0495ed39SKyle Evans /* return i * 9 */ 414*0495ed39SKyle Evans static Rand64 times9 (Rand64 i) { 415*0495ed39SKyle Evans return Iadd(Ishl(i, 3), i); /* i * 9 == (i << 3) + i */ 416*0495ed39SKyle Evans } 417*0495ed39SKyle Evans 418*0495ed39SKyle Evans /* return 'i' rotated left 'n' bits */ 419*0495ed39SKyle Evans static Rand64 rotl (Rand64 i, int n) { 420*0495ed39SKyle Evans lua_assert(n > 0 && n < 32); 421*0495ed39SKyle Evans return packI((i.h << n) | (trim32(i.l) >> (32 - n)), 422*0495ed39SKyle Evans (trim32(i.h) >> (32 - n)) | (i.l << n)); 423*0495ed39SKyle Evans } 424*0495ed39SKyle Evans 425*0495ed39SKyle Evans /* for offsets larger than 32, rotate right by 64 - offset */ 426*0495ed39SKyle Evans static Rand64 rotl1 (Rand64 i, int n) { 427*0495ed39SKyle Evans lua_assert(n > 32 && n < 64); 428*0495ed39SKyle Evans n = 64 - n; 429*0495ed39SKyle Evans return packI((trim32(i.h) >> n) | (i.l << (32 - n)), 430*0495ed39SKyle Evans (i.h << (32 - n)) | (trim32(i.l) >> n)); 431*0495ed39SKyle Evans } 432*0495ed39SKyle Evans 433*0495ed39SKyle Evans /* 434*0495ed39SKyle Evans ** implementation of 'xoshiro256**' algorithm on 'Rand64' values 435*0495ed39SKyle Evans */ 436*0495ed39SKyle Evans static Rand64 nextrand (Rand64 *state) { 437*0495ed39SKyle Evans Rand64 res = times9(rotl(times5(state[1]), 7)); 438*0495ed39SKyle Evans Rand64 t = Ishl(state[1], 17); 439*0495ed39SKyle Evans Ixor(&state[2], state[0]); 440*0495ed39SKyle Evans Ixor(&state[3], state[1]); 441*0495ed39SKyle Evans Ixor(&state[1], state[2]); 442*0495ed39SKyle Evans Ixor(&state[0], state[3]); 443*0495ed39SKyle Evans Ixor(&state[2], t); 444*0495ed39SKyle Evans state[3] = rotl1(state[3], 45); 445*0495ed39SKyle Evans return res; 446*0495ed39SKyle Evans } 447*0495ed39SKyle Evans 448*0495ed39SKyle Evans 449*0495ed39SKyle Evans /* 450*0495ed39SKyle Evans ** Converts a 'Rand64' into a float. 451*0495ed39SKyle Evans */ 452*0495ed39SKyle Evans 453*0495ed39SKyle Evans /* an unsigned 1 with proper type */ 454*0495ed39SKyle Evans #define UONE ((lu_int32)1) 455*0495ed39SKyle Evans 456*0495ed39SKyle Evans 457*0495ed39SKyle Evans #if FIGS <= 32 458*0495ed39SKyle Evans 459*0495ed39SKyle Evans /* 2^(-FIGS) */ 460*0495ed39SKyle Evans #define scaleFIG (l_mathop(0.5) / (UONE << (FIGS - 1))) 461*0495ed39SKyle Evans 462*0495ed39SKyle Evans /* 463*0495ed39SKyle Evans ** get up to 32 bits from higher half, shifting right to 464*0495ed39SKyle Evans ** throw out the extra bits. 465*0495ed39SKyle Evans */ 466*0495ed39SKyle Evans static lua_Number I2d (Rand64 x) { 467*0495ed39SKyle Evans lua_Number h = (lua_Number)(trim32(x.h) >> (32 - FIGS)); 468*0495ed39SKyle Evans return h * scaleFIG; 469*0495ed39SKyle Evans } 470*0495ed39SKyle Evans 471*0495ed39SKyle Evans #else /* 32 < FIGS <= 64 */ 472*0495ed39SKyle Evans 473*0495ed39SKyle Evans /* must take care to not shift stuff by more than 31 slots */ 474*0495ed39SKyle Evans 475*0495ed39SKyle Evans /* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */ 476*0495ed39SKyle Evans #define scaleFIG \ 477*0495ed39SKyle Evans ((lua_Number)1.0 / (UONE << 30) / 8.0 / (UONE << (FIGS - 33))) 478*0495ed39SKyle Evans 479*0495ed39SKyle Evans /* 480*0495ed39SKyle Evans ** use FIGS - 32 bits from lower half, throwing out the other 481*0495ed39SKyle Evans ** (32 - (FIGS - 32)) = (64 - FIGS) bits 482*0495ed39SKyle Evans */ 483*0495ed39SKyle Evans #define shiftLOW (64 - FIGS) 484*0495ed39SKyle Evans 485*0495ed39SKyle Evans /* 486*0495ed39SKyle Evans ** higher 32 bits go after those (FIGS - 32) bits: shiftHI = 2^(FIGS - 32) 487*0495ed39SKyle Evans */ 488*0495ed39SKyle Evans #define shiftHI ((lua_Number)(UONE << (FIGS - 33)) * 2.0) 489*0495ed39SKyle Evans 490*0495ed39SKyle Evans 491*0495ed39SKyle Evans static lua_Number I2d (Rand64 x) { 492*0495ed39SKyle Evans lua_Number h = (lua_Number)trim32(x.h) * shiftHI; 493*0495ed39SKyle Evans lua_Number l = (lua_Number)(trim32(x.l) >> shiftLOW); 494*0495ed39SKyle Evans return (h + l) * scaleFIG; 495*0495ed39SKyle Evans } 496*0495ed39SKyle Evans 497*0495ed39SKyle Evans #endif 498*0495ed39SKyle Evans 499*0495ed39SKyle Evans 500*0495ed39SKyle Evans /* convert a 'Rand64' to a 'lua_Unsigned' */ 501*0495ed39SKyle Evans static lua_Unsigned I2UInt (Rand64 x) { 502*0495ed39SKyle Evans return ((lua_Unsigned)trim32(x.h) << 31 << 1) | (lua_Unsigned)trim32(x.l); 503*0495ed39SKyle Evans } 504*0495ed39SKyle Evans 505*0495ed39SKyle Evans /* convert a 'lua_Unsigned' to a 'Rand64' */ 506*0495ed39SKyle Evans static Rand64 Int2I (lua_Unsigned n) { 507*0495ed39SKyle Evans return packI((lu_int32)(n >> 31 >> 1), (lu_int32)n); 508*0495ed39SKyle Evans } 509*0495ed39SKyle Evans 510*0495ed39SKyle Evans #endif /* } */ 511*0495ed39SKyle Evans 512*0495ed39SKyle Evans 513*0495ed39SKyle Evans /* 514*0495ed39SKyle Evans ** A state uses four 'Rand64' values. 515*0495ed39SKyle Evans */ 516*0495ed39SKyle Evans typedef struct { 517*0495ed39SKyle Evans Rand64 s[4]; 518*0495ed39SKyle Evans } RanState; 519*0495ed39SKyle Evans 520*0495ed39SKyle Evans 521*0495ed39SKyle Evans /* 522*0495ed39SKyle Evans ** Project the random integer 'ran' into the interval [0, n]. 523*0495ed39SKyle Evans ** Because 'ran' has 2^B possible values, the projection can only be 524*0495ed39SKyle Evans ** uniform when the size of the interval is a power of 2 (exact 525*0495ed39SKyle Evans ** division). Otherwise, to get a uniform projection into [0, n], we 526*0495ed39SKyle Evans ** first compute 'lim', the smallest Mersenne number not smaller than 527*0495ed39SKyle Evans ** 'n'. We then project 'ran' into the interval [0, lim]. If the result 528*0495ed39SKyle Evans ** is inside [0, n], we are done. Otherwise, we try with another 'ran', 529*0495ed39SKyle Evans ** until we have a result inside the interval. 530*0495ed39SKyle Evans */ 531*0495ed39SKyle Evans static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, 532*0495ed39SKyle Evans RanState *state) { 533*0495ed39SKyle Evans if ((n & (n + 1)) == 0) /* is 'n + 1' a power of 2? */ 534*0495ed39SKyle Evans return ran & n; /* no bias */ 535*0495ed39SKyle Evans else { 536*0495ed39SKyle Evans lua_Unsigned lim = n; 537*0495ed39SKyle Evans /* compute the smallest (2^b - 1) not smaller than 'n' */ 538*0495ed39SKyle Evans lim |= (lim >> 1); 539*0495ed39SKyle Evans lim |= (lim >> 2); 540*0495ed39SKyle Evans lim |= (lim >> 4); 541*0495ed39SKyle Evans lim |= (lim >> 8); 542*0495ed39SKyle Evans lim |= (lim >> 16); 543*0495ed39SKyle Evans #if (LUA_MAXUNSIGNED >> 31) >= 3 544*0495ed39SKyle Evans lim |= (lim >> 32); /* integer type has more than 32 bits */ 545*0495ed39SKyle Evans #endif 546*0495ed39SKyle Evans lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */ 547*0495ed39SKyle Evans && lim >= n /* not smaller than 'n', */ 548*0495ed39SKyle Evans && (lim >> 1) < n); /* and it is the smallest one */ 549*0495ed39SKyle Evans while ((ran &= lim) > n) /* project 'ran' into [0..lim] */ 550*0495ed39SKyle Evans ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */ 551*0495ed39SKyle Evans return ran; 552*0495ed39SKyle Evans } 553*0495ed39SKyle Evans } 554*0495ed39SKyle Evans 555*0495ed39SKyle Evans 5568e3e3a7aSWarner Losh static int math_random (lua_State *L) { 5578e3e3a7aSWarner Losh lua_Integer low, up; 558*0495ed39SKyle Evans lua_Unsigned p; 559*0495ed39SKyle Evans RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); 560*0495ed39SKyle Evans Rand64 rv = nextrand(state->s); /* next pseudo-random value */ 5618e3e3a7aSWarner Losh switch (lua_gettop(L)) { /* check number of arguments */ 5628e3e3a7aSWarner Losh case 0: { /* no arguments */ 563*0495ed39SKyle Evans lua_pushnumber(L, I2d(rv)); /* float between 0 and 1 */ 5648e3e3a7aSWarner Losh return 1; 5658e3e3a7aSWarner Losh } 5668e3e3a7aSWarner Losh case 1: { /* only upper limit */ 5678e3e3a7aSWarner Losh low = 1; 5688e3e3a7aSWarner Losh up = luaL_checkinteger(L, 1); 569*0495ed39SKyle Evans if (up == 0) { /* single 0 as argument? */ 570*0495ed39SKyle Evans lua_pushinteger(L, I2UInt(rv)); /* full random integer */ 571*0495ed39SKyle Evans return 1; 572*0495ed39SKyle Evans } 5738e3e3a7aSWarner Losh break; 5748e3e3a7aSWarner Losh } 5758e3e3a7aSWarner Losh case 2: { /* lower and upper limits */ 5768e3e3a7aSWarner Losh low = luaL_checkinteger(L, 1); 5778e3e3a7aSWarner Losh up = luaL_checkinteger(L, 2); 5788e3e3a7aSWarner Losh break; 5798e3e3a7aSWarner Losh } 5808e3e3a7aSWarner Losh default: return luaL_error(L, "wrong number of arguments"); 5818e3e3a7aSWarner Losh } 5828e3e3a7aSWarner Losh /* random integer in the interval [low, up] */ 5838e3e3a7aSWarner Losh luaL_argcheck(L, low <= up, 1, "interval is empty"); 584*0495ed39SKyle Evans /* project random integer into the interval [0, up - low] */ 585*0495ed39SKyle Evans p = project(I2UInt(rv), (lua_Unsigned)up - (lua_Unsigned)low, state); 586*0495ed39SKyle Evans lua_pushinteger(L, p + (lua_Unsigned)low); 5878e3e3a7aSWarner Losh return 1; 5888e3e3a7aSWarner Losh } 5898e3e3a7aSWarner Losh 5908e3e3a7aSWarner Losh 591*0495ed39SKyle Evans static void setseed (lua_State *L, Rand64 *state, 592*0495ed39SKyle Evans lua_Unsigned n1, lua_Unsigned n2) { 593*0495ed39SKyle Evans int i; 594*0495ed39SKyle Evans state[0] = Int2I(n1); 595*0495ed39SKyle Evans state[1] = Int2I(0xff); /* avoid a zero state */ 596*0495ed39SKyle Evans state[2] = Int2I(n2); 597*0495ed39SKyle Evans state[3] = Int2I(0); 598*0495ed39SKyle Evans for (i = 0; i < 16; i++) 599*0495ed39SKyle Evans nextrand(state); /* discard initial values to "spread" seed */ 600*0495ed39SKyle Evans lua_pushinteger(L, n1); 601*0495ed39SKyle Evans lua_pushinteger(L, n2); 602*0495ed39SKyle Evans } 603*0495ed39SKyle Evans 604*0495ed39SKyle Evans 605*0495ed39SKyle Evans /* 606*0495ed39SKyle Evans ** Set a "random" seed. To get some randomness, use the current time 607*0495ed39SKyle Evans ** and the address of 'L' (in case the machine does address space layout 608*0495ed39SKyle Evans ** randomization). 609*0495ed39SKyle Evans */ 610*0495ed39SKyle Evans static void randseed (lua_State *L, RanState *state) { 611*0495ed39SKyle Evans lua_Unsigned seed1 = (lua_Unsigned)time(NULL); 612*0495ed39SKyle Evans lua_Unsigned seed2 = (lua_Unsigned)(size_t)L; 613*0495ed39SKyle Evans setseed(L, state->s, seed1, seed2); 614*0495ed39SKyle Evans } 615*0495ed39SKyle Evans 616*0495ed39SKyle Evans 6178e3e3a7aSWarner Losh static int math_randomseed (lua_State *L) { 618*0495ed39SKyle Evans RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); 619*0495ed39SKyle Evans if (lua_isnone(L, 1)) { 620*0495ed39SKyle Evans randseed(L, state); 6218e3e3a7aSWarner Losh } 6228e3e3a7aSWarner Losh else { 623*0495ed39SKyle Evans lua_Integer n1 = luaL_checkinteger(L, 1); 624*0495ed39SKyle Evans lua_Integer n2 = luaL_optinteger(L, 2, 0); 625*0495ed39SKyle Evans setseed(L, state->s, n1, n2); 6268e3e3a7aSWarner Losh } 627*0495ed39SKyle Evans return 2; /* return seeds */ 6288e3e3a7aSWarner Losh } 6298e3e3a7aSWarner Losh 6308e3e3a7aSWarner Losh 631*0495ed39SKyle Evans static const luaL_Reg randfuncs[] = { 632*0495ed39SKyle Evans {"random", math_random}, 633*0495ed39SKyle Evans {"randomseed", math_randomseed}, 634*0495ed39SKyle Evans {NULL, NULL} 635*0495ed39SKyle Evans }; 636*0495ed39SKyle Evans 637*0495ed39SKyle Evans 638*0495ed39SKyle Evans /* 639*0495ed39SKyle Evans ** Register the random functions and initialize their state. 640*0495ed39SKyle Evans */ 641*0495ed39SKyle Evans static void setrandfunc (lua_State *L) { 642*0495ed39SKyle Evans RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0); 643*0495ed39SKyle Evans randseed(L, state); /* initialize with a "random" seed */ 644*0495ed39SKyle Evans lua_pop(L, 2); /* remove pushed seeds */ 645*0495ed39SKyle Evans luaL_setfuncs(L, randfuncs, 1); 646*0495ed39SKyle Evans } 647*0495ed39SKyle Evans 648*0495ed39SKyle Evans /* }================================================================== */ 649*0495ed39SKyle Evans 650*0495ed39SKyle Evans 6518e3e3a7aSWarner Losh /* 6528e3e3a7aSWarner Losh ** {================================================================== 6538e3e3a7aSWarner Losh ** Deprecated functions (for compatibility only) 6548e3e3a7aSWarner Losh ** =================================================================== 6558e3e3a7aSWarner Losh */ 6568e3e3a7aSWarner Losh #if defined(LUA_COMPAT_MATHLIB) 6578e3e3a7aSWarner Losh 6588e3e3a7aSWarner Losh static int math_cosh (lua_State *L) { 6598e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); 6608e3e3a7aSWarner Losh return 1; 6618e3e3a7aSWarner Losh } 6628e3e3a7aSWarner Losh 6638e3e3a7aSWarner Losh static int math_sinh (lua_State *L) { 6648e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); 6658e3e3a7aSWarner Losh return 1; 6668e3e3a7aSWarner Losh } 6678e3e3a7aSWarner Losh 6688e3e3a7aSWarner Losh static int math_tanh (lua_State *L) { 6698e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); 6708e3e3a7aSWarner Losh return 1; 6718e3e3a7aSWarner Losh } 6728e3e3a7aSWarner Losh 6738e3e3a7aSWarner Losh static int math_pow (lua_State *L) { 6748e3e3a7aSWarner Losh lua_Number x = luaL_checknumber(L, 1); 6758e3e3a7aSWarner Losh lua_Number y = luaL_checknumber(L, 2); 6768e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(pow)(x, y)); 6778e3e3a7aSWarner Losh return 1; 6788e3e3a7aSWarner Losh } 6798e3e3a7aSWarner Losh 6808e3e3a7aSWarner Losh static int math_frexp (lua_State *L) { 6818e3e3a7aSWarner Losh int e; 6828e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); 6838e3e3a7aSWarner Losh lua_pushinteger(L, e); 6848e3e3a7aSWarner Losh return 2; 6858e3e3a7aSWarner Losh } 6868e3e3a7aSWarner Losh 6878e3e3a7aSWarner Losh static int math_ldexp (lua_State *L) { 6888e3e3a7aSWarner Losh lua_Number x = luaL_checknumber(L, 1); 6898e3e3a7aSWarner Losh int ep = (int)luaL_checkinteger(L, 2); 6908e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(ldexp)(x, ep)); 6918e3e3a7aSWarner Losh return 1; 6928e3e3a7aSWarner Losh } 6938e3e3a7aSWarner Losh 6948e3e3a7aSWarner Losh static int math_log10 (lua_State *L) { 6958e3e3a7aSWarner Losh lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); 6968e3e3a7aSWarner Losh return 1; 6978e3e3a7aSWarner Losh } 6988e3e3a7aSWarner Losh 6998e3e3a7aSWarner Losh #endif 7008e3e3a7aSWarner Losh /* }================================================================== */ 7018e3e3a7aSWarner Losh 7028e3e3a7aSWarner Losh 7038e3e3a7aSWarner Losh 7048e3e3a7aSWarner Losh static const luaL_Reg mathlib[] = { 7058e3e3a7aSWarner Losh {"abs", math_abs}, 7068e3e3a7aSWarner Losh {"acos", math_acos}, 7078e3e3a7aSWarner Losh {"asin", math_asin}, 7088e3e3a7aSWarner Losh {"atan", math_atan}, 7098e3e3a7aSWarner Losh {"ceil", math_ceil}, 7108e3e3a7aSWarner Losh {"cos", math_cos}, 7118e3e3a7aSWarner Losh {"deg", math_deg}, 7128e3e3a7aSWarner Losh {"exp", math_exp}, 7138e3e3a7aSWarner Losh {"tointeger", math_toint}, 7148e3e3a7aSWarner Losh {"floor", math_floor}, 7158e3e3a7aSWarner Losh {"fmod", math_fmod}, 7168e3e3a7aSWarner Losh {"ult", math_ult}, 7178e3e3a7aSWarner Losh {"log", math_log}, 7188e3e3a7aSWarner Losh {"max", math_max}, 7198e3e3a7aSWarner Losh {"min", math_min}, 7208e3e3a7aSWarner Losh {"modf", math_modf}, 7218e3e3a7aSWarner Losh {"rad", math_rad}, 7228e3e3a7aSWarner Losh {"sin", math_sin}, 7238e3e3a7aSWarner Losh {"sqrt", math_sqrt}, 7248e3e3a7aSWarner Losh {"tan", math_tan}, 7258e3e3a7aSWarner Losh {"type", math_type}, 7268e3e3a7aSWarner Losh #if defined(LUA_COMPAT_MATHLIB) 7278e3e3a7aSWarner Losh {"atan2", math_atan}, 7288e3e3a7aSWarner Losh {"cosh", math_cosh}, 7298e3e3a7aSWarner Losh {"sinh", math_sinh}, 7308e3e3a7aSWarner Losh {"tanh", math_tanh}, 7318e3e3a7aSWarner Losh {"pow", math_pow}, 7328e3e3a7aSWarner Losh {"frexp", math_frexp}, 7338e3e3a7aSWarner Losh {"ldexp", math_ldexp}, 7348e3e3a7aSWarner Losh {"log10", math_log10}, 7358e3e3a7aSWarner Losh #endif 7368e3e3a7aSWarner Losh /* placeholders */ 737*0495ed39SKyle Evans {"random", NULL}, 738*0495ed39SKyle Evans {"randomseed", NULL}, 7398e3e3a7aSWarner Losh {"pi", NULL}, 7408e3e3a7aSWarner Losh {"huge", NULL}, 7418e3e3a7aSWarner Losh {"maxinteger", NULL}, 7428e3e3a7aSWarner Losh {"mininteger", NULL}, 7438e3e3a7aSWarner Losh {NULL, NULL} 7448e3e3a7aSWarner Losh }; 7458e3e3a7aSWarner Losh 7468e3e3a7aSWarner Losh 7478e3e3a7aSWarner Losh /* 7488e3e3a7aSWarner Losh ** Open math library 7498e3e3a7aSWarner Losh */ 7508e3e3a7aSWarner Losh LUAMOD_API int luaopen_math (lua_State *L) { 7518e3e3a7aSWarner Losh luaL_newlib(L, mathlib); 7528e3e3a7aSWarner Losh lua_pushnumber(L, PI); 7538e3e3a7aSWarner Losh lua_setfield(L, -2, "pi"); 7548e3e3a7aSWarner Losh lua_pushnumber(L, (lua_Number)HUGE_VAL); 7558e3e3a7aSWarner Losh lua_setfield(L, -2, "huge"); 7568e3e3a7aSWarner Losh lua_pushinteger(L, LUA_MAXINTEGER); 7578e3e3a7aSWarner Losh lua_setfield(L, -2, "maxinteger"); 7588e3e3a7aSWarner Losh lua_pushinteger(L, LUA_MININTEGER); 7598e3e3a7aSWarner Losh lua_setfield(L, -2, "mininteger"); 760*0495ed39SKyle Evans setrandfunc(L); 7618e3e3a7aSWarner Losh return 1; 7628e3e3a7aSWarner Losh } 7638e3e3a7aSWarner Losh 764