1/* $NetBSD$ */ 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 28static int math_abs (lua_State *L) { 29 lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); 30 return 1; 31} 32 33static int math_sin (lua_State *L) { 34 lua_pushnumber(L, sin(luaL_checknumber(L, 1))); 35 return 1; 36} 37 38static int math_sinh (lua_State *L) { 39 lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); 40 return 1; 41} 42 43static int math_cos (lua_State *L) { 44 lua_pushnumber(L, cos(luaL_checknumber(L, 1))); 45 return 1; 46} 47 48static int math_cosh (lua_State *L) { 49 lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); 50 return 1; 51} 52 53static int math_tan (lua_State *L) { 54 lua_pushnumber(L, tan(luaL_checknumber(L, 1))); 55 return 1; 56} 57 58static int math_tanh (lua_State *L) { 59 lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); 60 return 1; 61} 62 63static int math_asin (lua_State *L) { 64 lua_pushnumber(L, asin(luaL_checknumber(L, 1))); 65 return 1; 66} 67 68static int math_acos (lua_State *L) { 69 lua_pushnumber(L, acos(luaL_checknumber(L, 1))); 70 return 1; 71} 72 73static int math_atan (lua_State *L) { 74 lua_pushnumber(L, atan(luaL_checknumber(L, 1))); 75 return 1; 76} 77 78static int math_atan2 (lua_State *L) { 79 lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 80 return 1; 81} 82 83static int math_ceil (lua_State *L) { 84 lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); 85 return 1; 86} 87 88static int math_floor (lua_State *L) { 89 lua_pushnumber(L, floor(luaL_checknumber(L, 1))); 90 return 1; 91} 92 93static int math_fmod (lua_State *L) { 94 lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 95 return 1; 96} 97 98static 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 106static int math_sqrt (lua_State *L) { 107 lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); 108 return 1; 109} 110 111static int math_pow (lua_State *L) { 112 lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 113 return 1; 114} 115 116static int math_log (lua_State *L) { 117 lua_pushnumber(L, log(luaL_checknumber(L, 1))); 118 return 1; 119} 120 121static int math_log10 (lua_State *L) { 122 lua_pushnumber(L, log10(luaL_checknumber(L, 1))); 123 return 1; 124} 125 126static int math_exp (lua_State *L) { 127 lua_pushnumber(L, exp(luaL_checknumber(L, 1))); 128 return 1; 129} 130 131static int math_deg (lua_State *L) { 132 lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); 133 return 1; 134} 135 136static int math_rad (lua_State *L) { 137 lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); 138 return 1; 139} 140 141static 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 148static 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 155static 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 169static 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 183static 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 211static int math_randomseed (lua_State *L) { 212 srand(luaL_checkint(L, 1)); 213 return 0; 214} 215 216 217static 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*/ 253LUALIB_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