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