- /* 
- ** $Id: lmathlib.c,v 1.119.1.1 2017/04/19 17:20:42 roberto Exp $ 
- ** Standard mathematical library 
- ** See Copyright Notice in lua.h 
- */ 
-   
- #define lmathlib_c 
- #define LUA_LIB 
-   
- #include "lprefix.h" 
-   
-   
- #include <stdlib.h> 
- #include <math.h> 
-   
- #include "lua.h" 
-   
- #include "lauxlib.h" 
- #include "lualib.h" 
-   
-   
- #undef PI 
- #define PI      (l_mathop(3.141592653589793238462643383279502884)) 
-   
-   
- #if !defined(l_rand)            /* { */ 
- #if defined(LUA_USE_POSIX) 
- #define l_rand()        random() 
- #define l_srand(x)      srandom(x) 
- #define L_RANDMAX       2147483647      /* (2^31 - 1), following POSIX */ 
- #else 
- #define l_rand()        rand() 
- #define l_srand(x)      srand(x) 
- #define L_RANDMAX       RAND_MAX 
- #endif 
- #endif                          /* } */ 
-   
-   
- static int math_abs (lua_State *L) { 
-   if (lua_isinteger(L, 1)) { 
-     lua_Integer n = lua_tointeger(L, 1); 
-     if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n); 
-     lua_pushinteger(L, n); 
-   } 
-   else 
-     lua_pushnumber (- L ,-  l_mathop (fabs)(- luaL_checknumber (- L , 1)));
-   return 1; 
- } 
-   
- static int math_sin (lua_State *L) { 
-   lua_pushnumber (- L ,-  l_mathop (sin)(- luaL_checknumber (- L , 1)));
-   return 1; 
- } 
-   
- static int math_cos (lua_State *L) { 
-   lua_pushnumber (- L ,-  l_mathop (cos)(- luaL_checknumber (- L , 1)));
-   return 1; 
- } 
-   
- static int math_tan (lua_State *L) { 
-   lua_pushnumber (- L ,-  l_mathop (tan)(- luaL_checknumber (- L , 1)));
-   return 1; 
- } 
-   
- static int math_asin (lua_State *L) { 
-   lua_pushnumber (- L ,-  l_mathop (asin)(- luaL_checknumber (- L , 1)));
-   return 1; 
- } 
-   
- static int math_acos (lua_State *L) { 
-   lua_pushnumber (- L ,-  l_mathop (acos)(- luaL_checknumber (- L , 1)));
-   return 1; 
- } 
-   
- static int math_atan (lua_State *L) { 
-   lua_Number y = luaL_checknumber(L, 1); 
-   lua_Number x = luaL_optnumber(L, 2, 1); 
-   lua_pushnumber (- L ,-  l_mathop (atan2)(- y ,-  x ));
-   return 1; 
- } 
-   
-   
- static int math_toint (lua_State *L) { 
-   int valid; 
-   lua_Integer n = lua_tointegerx(L, 1, &valid); 
-   if (valid) 
-     lua_pushinteger(L, n); 
-   else { 
-     luaL_checkany(L, 1); 
-     lua_pushnil(L);  /* value is not convertible to integer */ 
-   } 
-   return 1; 
- } 
-   
-   
- static void pushnumint (lua_State *L, lua_Number d) { 
-   lua_Integer n; 
-   if (lua_numbertointeger(d, &n))  /* does 'd' fit in an integer? */ 
-     lua_pushinteger(L, n);  /* result is integer */ 
-   else 
-     lua_pushnumber(L, d);  /* result is float */ 
- } 
-   
-   
- static int math_floor (lua_State *L) { 
-   if (lua_isinteger(L, 1)) 
-     lua_settop(L, 1);  /* integer is its own floor */ 
-   else { 
-     lua_Number d  =-  l_mathop (floor)(- luaL_checknumber (- L , 1));
-     pushnumint(L, d); 
-   } 
-   return 1; 
- } 
-   
-   
- static int math_ceil (lua_State *L) { 
-   if (lua_isinteger(L, 1)) 
-     lua_settop(L, 1);  /* integer is its own ceil */ 
-   else { 
-     lua_Number d  =-  l_mathop (ceil)(- luaL_checknumber (- L , 1));
-     pushnumint(L, d); 
-   } 
-   return 1; 
- } 
-   
-   
- static int math_fmod (lua_State *L) { 
-   if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { 
-     lua_Integer d = lua_tointeger(L, 2); 
-     if ((lua_Unsigned)d + 1u <= 1u) {  /* special cases: -1 or 0 */ 
-       luaL_argcheck(L, d != 0, 2, "zero"); 
-       lua_pushinteger(L, 0);  /* avoid overflow with 0x80000... / -1 */ 
-     } 
-     else 
-       lua_pushinteger(L, lua_tointeger(L, 1) % d); 
-   } 
-   else 
-     lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), 
-                                      luaL_checknumber(L, 2))); 
-   return 1; 
- } 
-   
-   
- /* 
- ** next function does not use 'modf', avoiding problems with 'double*' 
- ** (which is not compatible with 'float*') when lua_Number is not 
- ** 'double'. 
- */ 
- static int math_modf (lua_State *L) { 
-   if (lua_isinteger(L ,1)) { 
-     lua_settop(L, 1);  /* number is its own integer part */ 
-     lua_pushnumber(L, 0);  /* no fractional part */ 
-   } 
-   else { 
-     lua_Number n = luaL_checknumber(L, 1); 
-     /* integer part (rounds toward zero) */ 
-     lua_Number ip  = (- n  < 0) ?-  l_mathop (ceil)(- n ) :-  l_mathop (floor)(- n );
-     pushnumint(L, ip); 
-     /* fractional part (test needed for inf/-inf) */ 
-     lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); 
-   } 
-   return 2; 
- } 
-   
-   
- static int math_sqrt (lua_State *L) { 
-   lua_pushnumber (- L ,-  l_mathop (sqrt)(- luaL_checknumber (- L , 1)));
-   return 1; 
- } 
-   
-   
- static int math_ult (lua_State *L) { 
-   lua_Integer a = luaL_checkinteger(L, 1); 
-   lua_Integer b = luaL_checkinteger(L, 2); 
-   lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b); 
-   return 1; 
- } 
-   
- static int math_log (lua_State *L) { 
-   lua_Number x = luaL_checknumber(L, 1); 
-   lua_Number res; 
-   if (lua_isnoneornil(L, 2)) 
-   else { 
-     lua_Number base = luaL_checknumber(L, 2); 
- #if !defined(LUA_USE_C89) 
-     if (base == l_mathop(2.0)) 
-       res = l_mathop(log2)(x); else 
- #endif 
-     if (base == l_mathop(10.0)) 
-       res  =-  l_mathop (log10)(- x );
-     else 
-       res  =-  l_mathop (log)(- x )/- l_mathop (log)(- base );
-   } 
-   lua_pushnumber(L, res); 
-   return 1; 
- } 
-   
- static int math_exp (lua_State *L) { 
-   lua_pushnumber (- L ,-  l_mathop (exp)(- luaL_checknumber (- L , 1)));
-   return 1; 
- } 
-   
- static int math_deg (lua_State *L) { 
-   lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI)); 
-   return 1; 
- } 
-   
- static int math_rad (lua_State *L) { 
-   lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0))); 
-   return 1; 
- } 
-   
-   
- static int math_min (lua_State *L) { 
-   int n = lua_gettop(L);  /* number of arguments */ 
-   int imin = 1;  /* index of current minimum value */ 
-   int i; 
-   luaL_argcheck(L, n >= 1, 1, "value expected"); 
-   for (i = 2; i <= n; i++) { 
-     if (lua_compare(L, i, imin, LUA_OPLT)) 
-       imin = i; 
-   } 
-   lua_pushvalue(L, imin); 
-   return 1; 
- } 
-   
-   
- static int math_max (lua_State *L) { 
-   int n = lua_gettop(L);  /* number of arguments */ 
-   int imax = 1;  /* index of current maximum value */ 
-   int i; 
-   luaL_argcheck(L, n >= 1, 1, "value expected"); 
-   for (i = 2; i <= n; i++) { 
-     if (lua_compare(L, imax, i, LUA_OPLT)) 
-       imax = i; 
-   } 
-   lua_pushvalue(L, imax); 
-   return 1; 
- } 
-   
- /* 
- ** 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 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; 
- } 
-   
-   
- static int math_type (lua_State *L) { 
-   if (lua_type(L, 1) == LUA_TNUMBER) { 
-       if (lua_isinteger(L, 1)) 
-         lua_pushliteral(L, "integer"); 
-       else 
-         lua_pushliteral(L, "float"); 
-   } 
-   else { 
-     luaL_checkany(L, 1); 
-     lua_pushnil(L); 
-   } 
-   return 1; 
- } 
-   
-   
- /* 
- ** {================================================================== 
- ** Deprecated functions (for compatibility only) 
- ** =================================================================== 
- */ 
- #if defined(LUA_COMPAT_MATHLIB) 
-   
- static int math_cosh (lua_State *L) { 
-   lua_pushnumber (- L ,-  l_mathop (cosh)(- luaL_checknumber (- L , 1)));
-   return 1; 
- } 
-   
- static int math_sinh (lua_State *L) { 
-   lua_pushnumber (- L ,-  l_mathop (sinh)(- luaL_checknumber (- L , 1)));
-   return 1; 
- } 
-   
- static int math_tanh (lua_State *L) { 
-   lua_pushnumber (- L ,-  l_mathop (tanh)(- luaL_checknumber (- L , 1)));
-   return 1; 
- } 
-   
- static int math_pow (lua_State *L) { 
-   lua_Number x = luaL_checknumber(L, 1); 
-   lua_Number y = luaL_checknumber(L, 2); 
-   lua_pushnumber (- L ,-  l_mathop (pow)(- x ,-  y ));
-   return 1; 
- } 
-   
- static int math_frexp (lua_State *L) { 
-   int e; 
-   lua_pushnumber (- L ,-  l_mathop (frexp)(- luaL_checknumber (- L , 1), &- e ));
-   lua_pushinteger(L, e); 
-   return 2; 
- } 
-   
- static int math_ldexp (lua_State *L) { 
-   lua_Number x = luaL_checknumber(L, 1); 
-   int ep = (int)luaL_checkinteger(L, 2); 
-   lua_pushnumber (- L ,-  l_mathop (ldexp)(- x ,-  ep ));
-   return 1; 
- } 
-   
- static int math_log10 (lua_State *L) { 
-   lua_pushnumber (- L ,-  l_mathop (log10)(- luaL_checknumber (- L , 1)));
-   return 1; 
- } 
-   
- #endif 
- /* }================================================================== */ 
-   
-   
-   
- static const luaL_Reg mathlib[] = { 
-   {"abs",   math_abs}, 
-   {"acos",  math_acos}, 
-   {"asin",  math_asin}, 
-   {"atan",  math_atan}, 
-   {"ceil",  math_ceil}, 
-   {"cos",   math_cos}, 
-   {"deg",   math_deg}, 
-   {"exp",   math_exp}, 
-   {"tointeger", math_toint}, 
-   {"floor", math_floor}, 
-   {"fmod",   math_fmod}, 
-   {"ult",   math_ult}, 
-   {"log",   math_log}, 
-   {"max",   math_max}, 
-   {"min",   math_min}, 
-   {"modf",   math_modf}, 
-   {"rad",   math_rad}, 
-   {"random",     math_random}, 
-   {"randomseed", math_randomseed}, 
-   {"sin",   math_sin}, 
-   {"sqrt",  math_sqrt}, 
-   {"tan",   math_tan}, 
-   {"type", math_type}, 
- #if defined(LUA_COMPAT_MATHLIB) 
-   {"atan2", math_atan}, 
-   {"cosh",   math_cosh}, 
-   {"sinh",   math_sinh}, 
-   {"tanh",   math_tanh}, 
-   {"pow",   math_pow}, 
-   {"frexp", math_frexp}, 
-   {"ldexp", math_ldexp}, 
-   {"log10", math_log10}, 
- #endif 
-   /* placeholders */ 
-   {"pi", NULL}, 
-   {"huge", NULL}, 
-   {"maxinteger", NULL}, 
-   {"mininteger", NULL}, 
-   {NULL, NULL} 
- }; 
-   
-   
- /* 
- ** Open math library 
- */ 
- LUAMOD_API int luaopen_math (lua_State *L) { 
-   luaL_newlib(L, mathlib); 
-   lua_pushnumber(L, PI); 
-   lua_setfield(L, -2, "pi"); 
-   lua_pushnumber(L, (lua_Number)HUGE_VAL); 
-   lua_setfield(L, -2, "huge"); 
-   lua_pushinteger(L, LUA_MAXINTEGER); 
-   lua_setfield(L, -2, "maxinteger"); 
-   lua_pushinteger(L, LUA_MININTEGER); 
-   lua_setfield(L, -2, "mininteger"); 
-   return 1; 
- } 
-   
-