00001
00002
00003
00004
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
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);
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);
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
00204
00205 lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
00206 switch (lua_gettop(L)) {
00207 case 0: {
00208 lua_pushnumber(L, r);
00209 break;
00210 }
00211 case 1: {
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);
00215 break;
00216 }
00217 case 2: {
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);
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();
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
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