lua/lmathlib.c

Go to the documentation of this file.
00001 /*
00002 ** $Id: lmathlib.c,v 1.80 2011/07/05 12:49:35 roberto Exp $
00003 ** Standard mathematical library
00004 ** See Copyright Notice in lua.h
00005 */
00006 
00007 
00008 #include <stdlib.h>
00009 #include <math.h>
00010 
00011 #define lmathlib_c
00012 #define LUA_LIB
00013 
00014 #include "lua.h"
00015 
00016 #include "lauxlib.h"
00017 #include "lualib.h"
00018 
00019 
00020 #undef PI
00021 #define PI (3.14159265358979323846)
00022 #define RADIANS_PER_DEGREE (PI/180.0)
00023 
00024 
00025 /* macro 'l_tg' allows the addition of an 'l' or 'f' to all math operations */
00026 #if !defined(l_tg)
00027 #define l_tg(x)     (x)
00028 #endif
00029 
00030 
00031 
00032 static int math_abs (lua_State *L) {
00033   lua_pushnumber(L, l_tg(fabs)(luaL_checknumber(L, 1)));
00034   return 1;
00035 }
00036 
00037 static int math_sin (lua_State *L) {
00038   lua_pushnumber(L, l_tg(sin)(luaL_checknumber(L, 1)));
00039   return 1;
00040 }
00041 
00042 static int math_sinh (lua_State *L) {
00043   lua_pushnumber(L, l_tg(sinh)(luaL_checknumber(L, 1)));
00044   return 1;
00045 }
00046 
00047 static int math_cos (lua_State *L) {
00048   lua_pushnumber(L, l_tg(cos)(luaL_checknumber(L, 1)));
00049   return 1;
00050 }
00051 
00052 static int math_cosh (lua_State *L) {
00053   lua_pushnumber(L, l_tg(cosh)(luaL_checknumber(L, 1)));
00054   return 1;
00055 }
00056 
00057 static int math_tan (lua_State *L) {
00058   lua_pushnumber(L, l_tg(tan)(luaL_checknumber(L, 1)));
00059   return 1;
00060 }
00061 
00062 static int math_tanh (lua_State *L) {
00063   lua_pushnumber(L, l_tg(tanh)(luaL_checknumber(L, 1)));
00064   return 1;
00065 }
00066 
00067 static int math_asin (lua_State *L) {
00068   lua_pushnumber(L, l_tg(asin)(luaL_checknumber(L, 1)));
00069   return 1;
00070 }
00071 
00072 static int math_acos (lua_State *L) {
00073   lua_pushnumber(L, l_tg(acos)(luaL_checknumber(L, 1)));
00074   return 1;
00075 }
00076 
00077 static int math_atan (lua_State *L) {
00078   lua_pushnumber(L, l_tg(atan)(luaL_checknumber(L, 1)));
00079   return 1;
00080 }
00081 
00082 static int math_atan2 (lua_State *L) {
00083   lua_pushnumber(L, l_tg(atan2)(luaL_checknumber(L, 1),
00084                                 luaL_checknumber(L, 2)));
00085   return 1;
00086 }
00087 
00088 static int math_ceil (lua_State *L) {
00089   lua_pushnumber(L, l_tg(ceil)(luaL_checknumber(L, 1)));
00090   return 1;
00091 }
00092 
00093 static int math_floor (lua_State *L) {
00094   lua_pushnumber(L, l_tg(floor)(luaL_checknumber(L, 1)));
00095   return 1;
00096 }
00097 
00098 static int math_fmod (lua_State *L) {
00099   lua_pushnumber(L, l_tg(fmod)(luaL_checknumber(L, 1),
00100                                luaL_checknumber(L, 2)));
00101   return 1;
00102 }
00103 
00104 static int math_modf (lua_State *L) {
00105   lua_Number ip;
00106   lua_Number fp = l_tg(modf)(luaL_checknumber(L, 1), &ip);
00107   lua_pushnumber(L, ip);
00108   lua_pushnumber(L, fp);
00109   return 2;
00110 }
00111 
00112 static int math_sqrt (lua_State *L) {
00113   lua_pushnumber(L, l_tg(sqrt)(luaL_checknumber(L, 1)));
00114   return 1;
00115 }
00116 
00117 static int math_pow (lua_State *L) {
00118   lua_pushnumber(L, l_tg(pow)(luaL_checknumber(L, 1),
00119                               luaL_checknumber(L, 2)));
00120   return 1;
00121 }
00122 
00123 static int math_log (lua_State *L) {
00124   lua_Number x = luaL_checknumber(L, 1);
00125   lua_Number res;
00126   if (lua_isnoneornil(L, 2))
00127     res = l_tg(log)(x);
00128   else {
00129     lua_Number base = luaL_checknumber(L, 2);
00130     if (base == 10.0) res = l_tg(log10)(x);
00131     else res = l_tg(log)(x)/l_tg(log)(base);
00132   }
00133   lua_pushnumber(L, res);
00134   return 1;
00135 }
00136 
00137 #if defined(LUA_COMPAT_LOG10)
00138 static int math_log10 (lua_State *L) {
00139   lua_pushnumber(L, l_tg(log10)(luaL_checknumber(L, 1)));
00140   return 1;
00141 }
00142 #endif
00143 
00144 static int math_exp (lua_State *L) {
00145   lua_pushnumber(L, l_tg(exp)(luaL_checknumber(L, 1)));
00146   return 1;
00147 }
00148 
00149 static int math_deg (lua_State *L) {
00150   lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
00151   return 1;
00152 }
00153 
00154 static int math_rad (lua_State *L) {
00155   lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
00156   return 1;
00157 }
00158 
00159 static int math_frexp (lua_State *L) {
00160   int e;
00161   lua_pushnumber(L, l_tg(frexp)(luaL_checknumber(L, 1), &e));
00162   lua_pushinteger(L, e);
00163   return 2;
00164 }
00165 
00166 static int math_ldexp (lua_State *L) {
00167   lua_pushnumber(L, l_tg(ldexp)(luaL_checknumber(L, 1),
00168                                 luaL_checkint(L, 2)));
00169   return 1;
00170 }
00171 
00172 
00173 
00174 static int math_min (lua_State *L) {
00175   int n = lua_gettop(L);  /* number of arguments */
00176   lua_Number dmin = luaL_checknumber(L, 1);
00177   int i;
00178   for (i=2; i<=n; i++) {
00179     lua_Number d = luaL_checknumber(L, i);
00180     if (d < dmin)
00181       dmin = d;
00182   }
00183   lua_pushnumber(L, dmin);
00184   return 1;
00185 }
00186 
00187 
00188 static int math_max (lua_State *L) {
00189   int n = lua_gettop(L);  /* number of arguments */
00190   lua_Number dmax = luaL_checknumber(L, 1);
00191   int i;
00192   for (i=2; i<=n; i++) {
00193     lua_Number d = luaL_checknumber(L, i);
00194     if (d > dmax)
00195       dmax = d;
00196   }
00197   lua_pushnumber(L, dmax);
00198   return 1;
00199 }
00200 
00201 
00202 static int math_random (lua_State *L) {
00203   /* the `%' avoids the (rare) case of r==1, and is needed also because on
00204      some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
00205   lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
00206   switch (lua_gettop(L)) {  /* check number of arguments */
00207     case 0: {  /* no arguments */
00208       lua_pushnumber(L, r);  /* Number between 0 and 1 */
00209       break;
00210     }
00211     case 1: {  /* only upper limit */
00212       lua_Number u = luaL_checknumber(L, 1);
00213       luaL_argcheck(L, 1.0 <= u, 1, "interval is empty");
00214       lua_pushnumber(L, l_tg(floor)(r*u) + 1.0);  /* int in [1, u] */
00215       break;
00216     }
00217     case 2: {  /* lower and upper limits */
00218       lua_Number l = luaL_checknumber(L, 1);
00219       lua_Number u = luaL_checknumber(L, 2);
00220       luaL_argcheck(L, l <= u, 2, "interval is empty");
00221       lua_pushnumber(L, l_tg(floor)(r*(u-l+1)) + l);  /* int in [l, u] */
00222       break;
00223     }
00224     default: return luaL_error(L, "wrong number of arguments");
00225   }
00226   return 1;
00227 }
00228 
00229 
00230 static int math_randomseed (lua_State *L) {
00231   srand(luaL_checkunsigned(L, 1));
00232   (void)rand(); /* discard first value to avoid undesirable correlations */
00233   return 0;
00234 }
00235 
00236 
00237 static const luaL_Reg mathlib[] = {
00238   {"abs",   math_abs},
00239   {"acos",  math_acos},
00240   {"asin",  math_asin},
00241   {"atan2", math_atan2},
00242   {"atan",  math_atan},
00243   {"ceil",  math_ceil},
00244   {"cosh",   math_cosh},
00245   {"cos",   math_cos},
00246   {"deg",   math_deg},
00247   {"exp",   math_exp},
00248   {"floor", math_floor},
00249   {"fmod",   math_fmod},
00250   {"frexp", math_frexp},
00251   {"ldexp", math_ldexp},
00252 #if defined(LUA_COMPAT_LOG10)
00253   {"log10", math_log10},
00254 #endif
00255   {"log",   math_log},
00256   {"max",   math_max},
00257   {"min",   math_min},
00258   {"modf",   math_modf},
00259   {"pow",   math_pow},
00260   {"rad",   math_rad},
00261   {"random",     math_random},
00262   {"randomseed", math_randomseed},
00263   {"sinh",   math_sinh},
00264   {"sin",   math_sin},
00265   {"sqrt",  math_sqrt},
00266   {"tanh",   math_tanh},
00267   {"tan",   math_tan},
00268   {NULL, NULL}
00269 };
00270 
00271 
00272 /*
00273 ** Open math library
00274 */
00275 LUAMOD_API int luaopen_math (lua_State *L) {
00276   luaL_newlib(L, mathlib);
00277   lua_pushnumber(L, PI);
00278   lua_setfield(L, -2, "pi");
00279   lua_pushnumber(L, HUGE_VAL);
00280   lua_setfield(L, -2, "huge");
00281   return 1;
00282 }
00283 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:04 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs