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 static int math_abs (lua_State *L) {
00027 lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
00028 return 1;
00029 }
00030
00031 static int math_sin (lua_State *L) {
00032 lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
00033 return 1;
00034 }
00035
00036 static int math_sinh (lua_State *L) {
00037 lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
00038 return 1;
00039 }
00040
00041 static int math_cos (lua_State *L) {
00042 lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
00043 return 1;
00044 }
00045
00046 static int math_cosh (lua_State *L) {
00047 lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
00048 return 1;
00049 }
00050
00051 static int math_tan (lua_State *L) {
00052 lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
00053 return 1;
00054 }
00055
00056 static int math_tanh (lua_State *L) {
00057 lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
00058 return 1;
00059 }
00060
00061 static int math_asin (lua_State *L) {
00062 lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
00063 return 1;
00064 }
00065
00066 static int math_acos (lua_State *L) {
00067 lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
00068 return 1;
00069 }
00070
00071 static int math_atan (lua_State *L) {
00072 lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
00073 return 1;
00074 }
00075
00076 static int math_atan2 (lua_State *L) {
00077 lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
00078 return 1;
00079 }
00080
00081 static int math_ceil (lua_State *L) {
00082 lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
00083 return 1;
00084 }
00085
00086 static int math_floor (lua_State *L) {
00087 lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
00088 return 1;
00089 }
00090
00091 static int math_fmod (lua_State *L) {
00092 lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
00093 return 1;
00094 }
00095
00096 static int math_modf (lua_State *L) {
00097 double ip;
00098 double fp = modf(luaL_checknumber(L, 1), &ip);
00099 lua_pushnumber(L, ip);
00100 lua_pushnumber(L, fp);
00101 return 2;
00102 }
00103
00104 static int math_sqrt (lua_State *L) {
00105 lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
00106 return 1;
00107 }
00108
00109 static int math_pow (lua_State *L) {
00110 lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
00111 return 1;
00112 }
00113
00114 static int math_log (lua_State *L) {
00115 lua_pushnumber(L, log(luaL_checknumber(L, 1)));
00116 return 1;
00117 }
00118
00119 static int math_log10 (lua_State *L) {
00120 lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
00121 return 1;
00122 }
00123
00124 static int math_exp (lua_State *L) {
00125 lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
00126 return 1;
00127 }
00128
00129 static int math_deg (lua_State *L) {
00130 lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
00131 return 1;
00132 }
00133
00134 static int math_rad (lua_State *L) {
00135 lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
00136 return 1;
00137 }
00138
00139 static int math_frexp (lua_State *L) {
00140 int e;
00141 lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
00142 lua_pushinteger(L, e);
00143 return 2;
00144 }
00145
00146 static int math_ldexp (lua_State *L) {
00147 lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
00148 return 1;
00149 }
00150
00151
00152
00153 static int math_min (lua_State *L) {
00154 int n = lua_gettop(L);
00155 lua_Number dmin = luaL_checknumber(L, 1);
00156 int i;
00157 for (i=2; i<=n; i++) {
00158 lua_Number d = luaL_checknumber(L, i);
00159 if (d < dmin)
00160 dmin = d;
00161 }
00162 lua_pushnumber(L, dmin);
00163 return 1;
00164 }
00165
00166
00167 static int math_max (lua_State *L) {
00168 int n = lua_gettop(L);
00169 lua_Number dmax = luaL_checknumber(L, 1);
00170 int i;
00171 for (i=2; i<=n; i++) {
00172 lua_Number d = luaL_checknumber(L, i);
00173 if (d > dmax)
00174 dmax = d;
00175 }
00176 lua_pushnumber(L, dmax);
00177 return 1;
00178 }
00179
00180
00181 static int math_random (lua_State *L) {
00182
00183
00184 lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
00185 switch (lua_gettop(L)) {
00186 case 0: {
00187 lua_pushnumber(L, r);
00188 break;
00189 }
00190 case 1: {
00191 int u = luaL_checkint(L, 1);
00192 luaL_argcheck(L, 1<=u, 1, "interval is empty");
00193 lua_pushnumber(L, floor(r*u)+1);
00194 break;
00195 }
00196 case 2: {
00197 int l = luaL_checkint(L, 1);
00198 int u = luaL_checkint(L, 2);
00199 luaL_argcheck(L, l<=u, 2, "interval is empty");
00200 lua_pushnumber(L, floor(r*(u-l+1))+l);
00201 break;
00202 }
00203 default: return luaL_error(L, "wrong number of arguments");
00204 }
00205 return 1;
00206 }
00207
00208
00209 static int math_randomseed (lua_State *L) {
00210 srand(luaL_checkint(L, 1));
00211 return 0;
00212 }
00213
00214
00215 static const luaL_Reg mathlib[] = {
00216 {"abs", math_abs},
00217 {"acos", math_acos},
00218 {"asin", math_asin},
00219 {"atan2", math_atan2},
00220 {"atan", math_atan},
00221 {"ceil", math_ceil},
00222 {"cosh", math_cosh},
00223 {"cos", math_cos},
00224 {"deg", math_deg},
00225 {"exp", math_exp},
00226 {"floor", math_floor},
00227 {"fmod", math_fmod},
00228 {"frexp", math_frexp},
00229 {"ldexp", math_ldexp},
00230 {"log10", math_log10},
00231 {"log", math_log},
00232 {"max", math_max},
00233 {"min", math_min},
00234 {"modf", math_modf},
00235 {"pow", math_pow},
00236 {"rad", math_rad},
00237 {"random", math_random},
00238 {"randomseed", math_randomseed},
00239 {"sinh", math_sinh},
00240 {"sin", math_sin},
00241 {"sqrt", math_sqrt},
00242 {"tanh", math_tanh},
00243 {"tan", math_tan},
00244 {NULL, NULL}
00245 };
00246
00247
00248
00249
00250
00251 LUALIB_API int luaopen_math (lua_State *L) {
00252 luaL_register(L, LUA_MATHLIBNAME, mathlib);
00253 lua_pushnumber(L, PI);
00254 lua_setfield(L, -2, "pi");
00255 lua_pushnumber(L, HUGE_VAL);
00256 lua_setfield(L, -2, "huge");
00257 #if defined(LUA_COMPAT_MOD)
00258 lua_getfield(L, -1, "fmod");
00259 lua_setfield(L, -2, "mod");
00260 #endif
00261 return 1;
00262 }