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