Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2. ** $Id: lmathlib.c,v 1.80 2011/07/05 12:49:35 roberto Exp $
  3. ** Standard mathematical library
  4. ** See Copyright Notice in lua.h
  5. */
  6.  
  7.  
  8. #include <stdlib.h>
  9. #include <math.h>
  10.  
  11. #define lmathlib_c
  12. #define LUA_LIB
  13.  
  14. #include "lua.h"
  15.  
  16. #include "lauxlib.h"
  17. #include "lualib.h"
  18.  
  19.  
  20. #undef PI
  21. #define PI (3.14159265358979323846)
  22. #define RADIANS_PER_DEGREE (PI/180.0)
  23.  
  24.  
  25. /* macro 'l_tg' allows the addition of an 'l' or 'f' to all math operations */
  26. #if !defined(l_tg)
  27. #define l_tg(x)         (x)
  28. #endif
  29.  
  30.  
  31.  
  32. static int math_abs (lua_State *L) {
  33.   lua_pushnumber(L, l_tg(fabs)(luaL_checknumber(L, 1)));
  34.   return 1;
  35. }
  36.  
  37. static int math_sin (lua_State *L) {
  38.   lua_pushnumber(L, l_tg(sin)(luaL_checknumber(L, 1)));
  39.   return 1;
  40. }
  41.  
  42. static int math_sinh (lua_State *L) {
  43.   lua_pushnumber(L, l_tg(sinh)(luaL_checknumber(L, 1)));
  44.   return 1;
  45. }
  46.  
  47. static int math_cos (lua_State *L) {
  48.   lua_pushnumber(L, l_tg(cos)(luaL_checknumber(L, 1)));
  49.   return 1;
  50. }
  51.  
  52. static int math_cosh (lua_State *L) {
  53.   lua_pushnumber(L, l_tg(cosh)(luaL_checknumber(L, 1)));
  54.   return 1;
  55. }
  56.  
  57. static int math_tan (lua_State *L) {
  58.   lua_pushnumber(L, l_tg(tan)(luaL_checknumber(L, 1)));
  59.   return 1;
  60. }
  61.  
  62. static int math_tanh (lua_State *L) {
  63.   lua_pushnumber(L, l_tg(tanh)(luaL_checknumber(L, 1)));
  64.   return 1;
  65. }
  66.  
  67. static int math_asin (lua_State *L) {
  68.   lua_pushnumber(L, l_tg(asin)(luaL_checknumber(L, 1)));
  69.   return 1;
  70. }
  71.  
  72. static int math_acos (lua_State *L) {
  73.   lua_pushnumber(L, l_tg(acos)(luaL_checknumber(L, 1)));
  74.   return 1;
  75. }
  76.  
  77. static int math_atan (lua_State *L) {
  78.   lua_pushnumber(L, l_tg(atan)(luaL_checknumber(L, 1)));
  79.   return 1;
  80. }
  81.  
  82. static int math_atan2 (lua_State *L) {
  83.   lua_pushnumber(L, l_tg(atan2)(luaL_checknumber(L, 1),
  84.                                 luaL_checknumber(L, 2)));
  85.   return 1;
  86. }
  87.  
  88. static int math_ceil (lua_State *L) {
  89.   lua_pushnumber(L, l_tg(ceil)(luaL_checknumber(L, 1)));
  90.   return 1;
  91. }
  92.  
  93. static int math_floor (lua_State *L) {
  94.   lua_pushnumber(L, l_tg(floor)(luaL_checknumber(L, 1)));
  95.   return 1;
  96. }
  97.  
  98. static int math_fmod (lua_State *L) {
  99.   lua_pushnumber(L, l_tg(fmod)(luaL_checknumber(L, 1),
  100.                                luaL_checknumber(L, 2)));
  101.   return 1;
  102. }
  103.  
  104. static int math_modf (lua_State *L) {
  105.   lua_Number ip;
  106.   lua_Number fp = l_tg(modf)(luaL_checknumber(L, 1), &ip);
  107.   lua_pushnumber(L, ip);
  108.   lua_pushnumber(L, fp);
  109.   return 2;
  110. }
  111.  
  112. static int math_sqrt (lua_State *L) {
  113.   lua_pushnumber(L, l_tg(sqrt)(luaL_checknumber(L, 1)));
  114.   return 1;
  115. }
  116.  
  117. static int math_pow (lua_State *L) {
  118.   lua_pushnumber(L, l_tg(pow)(luaL_checknumber(L, 1),
  119.                               luaL_checknumber(L, 2)));
  120.   return 1;
  121. }
  122.  
  123. static int math_log (lua_State *L) {
  124.   lua_Number x = luaL_checknumber(L, 1);
  125.   lua_Number res;
  126.   if (lua_isnoneornil(L, 2))
  127.     res = l_tg(log)(x);
  128.   else {
  129.     lua_Number base = luaL_checknumber(L, 2);
  130.     if (base == 10.0) res = l_tg(log10)(x);
  131.     else res = l_tg(log)(x)/l_tg(log)(base);
  132.   }
  133.   lua_pushnumber(L, res);
  134.   return 1;
  135. }
  136.  
  137. #if defined(LUA_COMPAT_LOG10)
  138. static int math_log10 (lua_State *L) {
  139.   lua_pushnumber(L, l_tg(log10)(luaL_checknumber(L, 1)));
  140.   return 1;
  141. }
  142. #endif
  143.  
  144. static int math_exp (lua_State *L) {
  145.   lua_pushnumber(L, l_tg(exp)(luaL_checknumber(L, 1)));
  146.   return 1;
  147. }
  148.  
  149. static int math_deg (lua_State *L) {
  150.   lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
  151.   return 1;
  152. }
  153.  
  154. static int math_rad (lua_State *L) {
  155.   lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
  156.   return 1;
  157. }
  158.  
  159. static int math_frexp (lua_State *L) {
  160.   int e;
  161.   lua_pushnumber(L, l_tg(frexp)(luaL_checknumber(L, 1), &e));
  162.   lua_pushinteger(L, e);
  163.   return 2;
  164. }
  165.  
  166. static int math_ldexp (lua_State *L) {
  167.   lua_pushnumber(L, l_tg(ldexp)(luaL_checknumber(L, 1),
  168.                                 luaL_checkint(L, 2)));
  169.   return 1;
  170. }
  171.  
  172.  
  173.  
  174. static int math_min (lua_State *L) {
  175.   int n = lua_gettop(L);  /* number of arguments */
  176.   lua_Number dmin = luaL_checknumber(L, 1);
  177.   int i;
  178.   for (i=2; i<=n; i++) {
  179.     lua_Number d = luaL_checknumber(L, i);
  180.     if (d < dmin)
  181.       dmin = d;
  182.   }
  183.   lua_pushnumber(L, dmin);
  184.   return 1;
  185. }
  186.  
  187.  
  188. static int math_max (lua_State *L) {
  189.   int n = lua_gettop(L);  /* number of arguments */
  190.   lua_Number dmax = luaL_checknumber(L, 1);
  191.   int i;
  192.   for (i=2; i<=n; i++) {
  193.     lua_Number d = luaL_checknumber(L, i);
  194.     if (d > dmax)
  195.       dmax = d;
  196.   }
  197.   lua_pushnumber(L, dmax);
  198.   return 1;
  199. }
  200.  
  201.  
  202. static int math_random (lua_State *L) {
  203.   /* the `%' avoids the (rare) case of r==1, and is needed also because on
  204.      some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
  205.   lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
  206.   switch (lua_gettop(L)) {  /* check number of arguments */
  207.     case 0: {  /* no arguments */
  208.       lua_pushnumber(L, r);  /* Number between 0 and 1 */
  209.       break;
  210.     }
  211.     case 1: {  /* only upper limit */
  212.       lua_Number u = luaL_checknumber(L, 1);
  213.       luaL_argcheck(L, 1.0 <= u, 1, "interval is empty");
  214.       lua_pushnumber(L, l_tg(floor)(r*u) + 1.0);  /* int in [1, u] */
  215.       break;
  216.     }
  217.     case 2: {  /* lower and upper limits */
  218.       lua_Number l = luaL_checknumber(L, 1);
  219.       lua_Number u = luaL_checknumber(L, 2);
  220.       luaL_argcheck(L, l <= u, 2, "interval is empty");
  221.       lua_pushnumber(L, l_tg(floor)(r*(u-l+1)) + l);  /* int in [l, u] */
  222.       break;
  223.     }
  224.     default: return luaL_error(L, "wrong number of arguments");
  225.   }
  226.   return 1;
  227. }
  228.  
  229.  
  230. static int math_randomseed (lua_State *L) {
  231.   srand(luaL_checkunsigned(L, 1));
  232.   (void)rand(); /* discard first value to avoid undesirable correlations */
  233.   return 0;
  234. }
  235.  
  236.  
  237. static const luaL_Reg mathlib[] = {
  238.   {"abs",   math_abs},
  239.   {"acos",  math_acos},
  240.   {"asin",  math_asin},
  241.   {"atan2", math_atan2},
  242.   {"atan",  math_atan},
  243.   {"ceil",  math_ceil},
  244.   {"cosh",   math_cosh},
  245.   {"cos",   math_cos},
  246.   {"deg",   math_deg},
  247.   {"exp",   math_exp},
  248.   {"floor", math_floor},
  249.   {"fmod",   math_fmod},
  250.   {"frexp", math_frexp},
  251.   {"ldexp", math_ldexp},
  252. #if defined(LUA_COMPAT_LOG10)
  253.   {"log10", math_log10},
  254. #endif
  255.   {"log",   math_log},
  256.   {"max",   math_max},
  257.   {"min",   math_min},
  258.   {"modf",   math_modf},
  259.   {"pow",   math_pow},
  260.   {"rad",   math_rad},
  261.   {"random",     math_random},
  262.   {"randomseed", math_randomseed},
  263.   {"sinh",   math_sinh},
  264.   {"sin",   math_sin},
  265.   {"sqrt",  math_sqrt},
  266.   {"tanh",   math_tanh},
  267.   {"tan",   math_tan},
  268.   {NULL, NULL}
  269. };
  270.  
  271.  
  272. /*
  273. ** Open math library
  274. */
  275. LUAMOD_API int luaopen_math (lua_State *L) {
  276.   luaL_newlib(L, mathlib);
  277.   lua_pushnumber(L, PI);
  278.   lua_setfield(L, -2, "pi");
  279.   lua_pushnumber(L, HUGE_VAL);
  280.   lua_setfield(L, -2, "huge");
  281.   return 1;
  282. }
  283.  
  284.