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