?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2. ** $Id: lmathlib.c,v 1.119.1.1 2017/04/19 17:20:42 roberto Exp $
  3. ** Standard mathematical library
  4. ** See Copyright Notice in lua.h
  5. */
  6.  
  7. #define lmathlib_c
  8. #define LUA_LIB
  9.  
  10. #include "lprefix.h"
  11.  
  12.  
  13. #include <stdlib.h>
  14. #include <math.h>
  15.  
  16. #include "lua.h"
  17.  
  18. #include "lauxlib.h"
  19. #include "lualib.h"
  20.  
  21.  
  22. #undef PI
  23. #define PI      (l_mathop(3.141592653589793238462643383279502884))
  24.  
  25.  
  26. #if !defined(l_rand)            /* { */
  27. #if defined(LUA_USE_POSIX)
  28. #define l_rand()        random()
  29. #define l_srand(x)      srandom(x)
  30. #define L_RANDMAX       2147483647      /* (2^31 - 1), following POSIX */
  31. #else
  32. #define l_rand()        rand()
  33. #define l_srand(x)      srand(x)
  34. #define L_RANDMAX       RAND_MAX
  35. #endif
  36. #endif                          /* } */
  37.  
  38.  
  39. static int math_abs (lua_State *L) {
  40.   if (lua_isinteger(L, 1)) {
  41.     lua_Integer n = lua_tointeger(L, 1);
  42.     if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n);
  43.     lua_pushinteger(L, n);
  44.   }
  45.   else
  46.     lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
  47.   return 1;
  48. }
  49.  
  50. static int math_sin (lua_State *L) {
  51.   lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
  52.   return 1;
  53. }
  54.  
  55. static int math_cos (lua_State *L) {
  56.   lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
  57.   return 1;
  58. }
  59.  
  60. static int math_tan (lua_State *L) {
  61.   lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
  62.   return 1;
  63. }
  64.  
  65. static int math_asin (lua_State *L) {
  66.   lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
  67.   return 1;
  68. }
  69.  
  70. static int math_acos (lua_State *L) {
  71.   lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
  72.   return 1;
  73. }
  74.  
  75. static int math_atan (lua_State *L) {
  76.   lua_Number y = luaL_checknumber(L, 1);
  77.   lua_Number x = luaL_optnumber(L, 2, 1);
  78.   lua_pushnumber(L, l_mathop(atan2)(y, x));
  79.   return 1;
  80. }
  81.  
  82.  
  83. static int math_toint (lua_State *L) {
  84.   int valid;
  85.   lua_Integer n = lua_tointegerx(L, 1, &valid);
  86.   if (valid)
  87.     lua_pushinteger(L, n);
  88.   else {
  89.     luaL_checkany(L, 1);
  90.     lua_pushnil(L);  /* value is not convertible to integer */
  91.   }
  92.   return 1;
  93. }
  94.  
  95.  
  96. static void pushnumint (lua_State *L, lua_Number d) {
  97.   lua_Integer n;
  98.   if (lua_numbertointeger(d, &n))  /* does 'd' fit in an integer? */
  99.     lua_pushinteger(L, n);  /* result is integer */
  100.   else
  101.     lua_pushnumber(L, d);  /* result is float */
  102. }
  103.  
  104.  
  105. static int math_floor (lua_State *L) {
  106.   if (lua_isinteger(L, 1))
  107.     lua_settop(L, 1);  /* integer is its own floor */
  108.   else {
  109.     lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1));
  110.     pushnumint(L, d);
  111.   }
  112.   return 1;
  113. }
  114.  
  115.  
  116. static int math_ceil (lua_State *L) {
  117.   if (lua_isinteger(L, 1))
  118.     lua_settop(L, 1);  /* integer is its own ceil */
  119.   else {
  120.     lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1));
  121.     pushnumint(L, d);
  122.   }
  123.   return 1;
  124. }
  125.  
  126.  
  127. static int math_fmod (lua_State *L) {
  128.   if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) {
  129.     lua_Integer d = lua_tointeger(L, 2);
  130.     if ((lua_Unsigned)d + 1u <= 1u) {  /* special cases: -1 or 0 */
  131.       luaL_argcheck(L, d != 0, 2, "zero");
  132.       lua_pushinteger(L, 0);  /* avoid overflow with 0x80000... / -1 */
  133.     }
  134.     else
  135.       lua_pushinteger(L, lua_tointeger(L, 1) % d);
  136.   }
  137.   else
  138.     lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
  139.                                      luaL_checknumber(L, 2)));
  140.   return 1;
  141. }
  142.  
  143.  
  144. /*
  145. ** next function does not use 'modf', avoiding problems with 'double*'
  146. ** (which is not compatible with 'float*') when lua_Number is not
  147. ** 'double'.
  148. */
  149. static int math_modf (lua_State *L) {
  150.   if (lua_isinteger(L ,1)) {
  151.     lua_settop(L, 1);  /* number is its own integer part */
  152.     lua_pushnumber(L, 0);  /* no fractional part */
  153.   }
  154.   else {
  155.     lua_Number n = luaL_checknumber(L, 1);
  156.     /* integer part (rounds toward zero) */
  157.     lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n);
  158.     pushnumint(L, ip);
  159.     /* fractional part (test needed for inf/-inf) */
  160.     lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip));
  161.   }
  162.   return 2;
  163. }
  164.  
  165.  
  166. static int math_sqrt (lua_State *L) {
  167.   lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
  168.   return 1;
  169. }
  170.  
  171.  
  172. static int math_ult (lua_State *L) {
  173.   lua_Integer a = luaL_checkinteger(L, 1);
  174.   lua_Integer b = luaL_checkinteger(L, 2);
  175.   lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b);
  176.   return 1;
  177. }
  178.  
  179. static int math_log (lua_State *L) {
  180.   lua_Number x = luaL_checknumber(L, 1);
  181.   lua_Number res;
  182.   if (lua_isnoneornil(L, 2))
  183.     res = l_mathop(log)(x);
  184.   else {
  185.     lua_Number base = luaL_checknumber(L, 2);
  186. #if !defined(LUA_USE_C89)
  187.     if (base == l_mathop(2.0))
  188.       res = l_mathop(log2)(x); else
  189. #endif
  190.     if (base == l_mathop(10.0))
  191.       res = l_mathop(log10)(x);
  192.     else
  193.       res = l_mathop(log)(x)/l_mathop(log)(base);
  194.   }
  195.   lua_pushnumber(L, res);
  196.   return 1;
  197. }
  198.  
  199. static int math_exp (lua_State *L) {
  200.   lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
  201.   return 1;
  202. }
  203.  
  204. static int math_deg (lua_State *L) {
  205.   lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI));
  206.   return 1;
  207. }
  208.  
  209. static int math_rad (lua_State *L) {
  210.   lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0)));
  211.   return 1;
  212. }
  213.  
  214.  
  215. static int math_min (lua_State *L) {
  216.   int n = lua_gettop(L);  /* number of arguments */
  217.   int imin = 1;  /* index of current minimum value */
  218.   int i;
  219.   luaL_argcheck(L, n >= 1, 1, "value expected");
  220.   for (i = 2; i <= n; i++) {
  221.     if (lua_compare(L, i, imin, LUA_OPLT))
  222.       imin = i;
  223.   }
  224.   lua_pushvalue(L, imin);
  225.   return 1;
  226. }
  227.  
  228.  
  229. static int math_max (lua_State *L) {
  230.   int n = lua_gettop(L);  /* number of arguments */
  231.   int imax = 1;  /* index of current maximum value */
  232.   int i;
  233.   luaL_argcheck(L, n >= 1, 1, "value expected");
  234.   for (i = 2; i <= n; i++) {
  235.     if (lua_compare(L, imax, i, LUA_OPLT))
  236.       imax = i;
  237.   }
  238.   lua_pushvalue(L, imax);
  239.   return 1;
  240. }
  241.  
  242. /*
  243. ** This function uses 'double' (instead of 'lua_Number') to ensure that
  244. ** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0'
  245. ** will keep full precision (ensuring that 'r' is always less than 1.0.)
  246. */
  247. static int math_random (lua_State *L) {
  248.   lua_Integer low, up;
  249.   double r = (double)l_rand() * (1.0 / ((double)L_RANDMAX + 1.0));
  250.   switch (lua_gettop(L)) {  /* check number of arguments */
  251.     case 0: {  /* no arguments */
  252.       lua_pushnumber(L, (lua_Number)r);  /* Number between 0 and 1 */
  253.       return 1;
  254.     }
  255.     case 1: {  /* only upper limit */
  256.       low = 1;
  257.       up = luaL_checkinteger(L, 1);
  258.       break;
  259.     }
  260.     case 2: {  /* lower and upper limits */
  261.       low = luaL_checkinteger(L, 1);
  262.       up = luaL_checkinteger(L, 2);
  263.       break;
  264.     }
  265.     default: return luaL_error(L, "wrong number of arguments");
  266.   }
  267.   /* random integer in the interval [low, up] */
  268.   luaL_argcheck(L, low <= up, 1, "interval is empty");
  269.   luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1,
  270.                    "interval too large");
  271.   r *= (double)(up - low) + 1.0;
  272.   lua_pushinteger(L, (lua_Integer)r + low);
  273.   return 1;
  274. }
  275.  
  276.  
  277. static int math_randomseed (lua_State *L) {
  278.   l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1));
  279.   (void)l_rand(); /* discard first value to avoid undesirable correlations */
  280.   return 0;
  281. }
  282.  
  283.  
  284. static int math_type (lua_State *L) {
  285.   if (lua_type(L, 1) == LUA_TNUMBER) {
  286.       if (lua_isinteger(L, 1))
  287.         lua_pushliteral(L, "integer");
  288.       else
  289.         lua_pushliteral(L, "float");
  290.   }
  291.   else {
  292.     luaL_checkany(L, 1);
  293.     lua_pushnil(L);
  294.   }
  295.   return 1;
  296. }
  297.  
  298.  
  299. /*
  300. ** {==================================================================
  301. ** Deprecated functions (for compatibility only)
  302. ** ===================================================================
  303. */
  304. #if defined(LUA_COMPAT_MATHLIB)
  305.  
  306. static int math_cosh (lua_State *L) {
  307.   lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
  308.   return 1;
  309. }
  310.  
  311. static int math_sinh (lua_State *L) {
  312.   lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
  313.   return 1;
  314. }
  315.  
  316. static int math_tanh (lua_State *L) {
  317.   lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
  318.   return 1;
  319. }
  320.  
  321. static int math_pow (lua_State *L) {
  322.   lua_Number x = luaL_checknumber(L, 1);
  323.   lua_Number y = luaL_checknumber(L, 2);
  324.   lua_pushnumber(L, l_mathop(pow)(x, y));
  325.   return 1;
  326. }
  327.  
  328. static int math_frexp (lua_State *L) {
  329.   int e;
  330.   lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
  331.   lua_pushinteger(L, e);
  332.   return 2;
  333. }
  334.  
  335. static int math_ldexp (lua_State *L) {
  336.   lua_Number x = luaL_checknumber(L, 1);
  337.   int ep = (int)luaL_checkinteger(L, 2);
  338.   lua_pushnumber(L, l_mathop(ldexp)(x, ep));
  339.   return 1;
  340. }
  341.  
  342. static int math_log10 (lua_State *L) {
  343.   lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
  344.   return 1;
  345. }
  346.  
  347. #endif
  348. /* }================================================================== */
  349.  
  350.  
  351.  
  352. static const luaL_Reg mathlib[] = {
  353.   {"abs",   math_abs},
  354.   {"acos",  math_acos},
  355.   {"asin",  math_asin},
  356.   {"atan",  math_atan},
  357.   {"ceil",  math_ceil},
  358.   {"cos",   math_cos},
  359.   {"deg",   math_deg},
  360.   {"exp",   math_exp},
  361.   {"tointeger", math_toint},
  362.   {"floor", math_floor},
  363.   {"fmod",   math_fmod},
  364.   {"ult",   math_ult},
  365.   {"log",   math_log},
  366.   {"max",   math_max},
  367.   {"min",   math_min},
  368.   {"modf",   math_modf},
  369.   {"rad",   math_rad},
  370.   {"random",     math_random},
  371.   {"randomseed", math_randomseed},
  372.   {"sin",   math_sin},
  373.   {"sqrt",  math_sqrt},
  374.   {"tan",   math_tan},
  375.   {"type", math_type},
  376. #if defined(LUA_COMPAT_MATHLIB)
  377.   {"atan2", math_atan},
  378.   {"cosh",   math_cosh},
  379.   {"sinh",   math_sinh},
  380.   {"tanh",   math_tanh},
  381.   {"pow",   math_pow},
  382.   {"frexp", math_frexp},
  383.   {"ldexp", math_ldexp},
  384.   {"log10", math_log10},
  385. #endif
  386.   /* placeholders */
  387.   {"pi", NULL},
  388.   {"huge", NULL},
  389.   {"maxinteger", NULL},
  390.   {"mininteger", NULL},
  391.   {NULL, NULL}
  392. };
  393.  
  394.  
  395. /*
  396. ** Open math library
  397. */
  398. LUAMOD_API int luaopen_math (lua_State *L) {
  399.   luaL_newlib(L, mathlib);
  400.   lua_pushnumber(L, PI);
  401.   lua_setfield(L, -2, "pi");
  402.   lua_pushnumber(L, (lua_Number)HUGE_VAL);
  403.   lua_setfield(L, -2, "huge");
  404.   lua_pushinteger(L, LUA_MAXINTEGER);
  405.   lua_setfield(L, -2, "maxinteger");
  406.   lua_pushinteger(L, LUA_MININTEGER);
  407.   lua_setfield(L, -2, "mininteger");
  408.   return 1;
  409. }
  410.  
  411.