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
18 /* 'luai_vectpow()' as a replacement for 'cpow()'. Defined in the header; we
19 * don't intrude the code libs internal functions.
27 # define PI (3.14159265358979323846F)
31 # define PI (3.14159265358979323846264338327950288)
33 #define RADIANS_PER_DEGREE (PI/180)
37 # define HUGE HUGE_VALF
38 #elif defined(LNUM_LDOUBLE)
39 # define HUGE HUGE_VALL
41 # define HUGE HUGE_VAL
44 static int math_abs (lua_State *L) {
46 lua_pushnumber(L, _LF(cabs) (luaL_checkcomplex(L,1)));
48 lua_pushnumber(L, _LF(fabs) (luaL_checknumber(L, 1)));
53 static int math_sin (lua_State *L) {
55 lua_pushcomplex(L, _LF(csin) (luaL_checkcomplex(L,1)));
57 lua_pushnumber(L, _LF(sin) (luaL_checknumber(L, 1)));
62 static int math_sinh (lua_State *L) {
64 lua_pushcomplex(L, _LF(csinh) (luaL_checkcomplex(L,1)));
66 lua_pushnumber(L, _LF(sinh) (luaL_checknumber(L, 1)));
71 static int math_cos (lua_State *L) {
73 lua_pushcomplex(L, _LF(ccos) (luaL_checkcomplex(L,1)));
75 lua_pushnumber(L, _LF(cos) (luaL_checknumber(L, 1)));
80 static int math_cosh (lua_State *L) {
82 lua_pushcomplex(L, _LF(ccosh) (luaL_checkcomplex(L,1)));
84 lua_pushnumber(L, _LF(cosh) (luaL_checknumber(L, 1)));
89 static int math_tan (lua_State *L) {
91 lua_pushcomplex(L, _LF(ctan) (luaL_checkcomplex(L,1)));
93 lua_pushnumber(L, _LF(tan) (luaL_checknumber(L, 1)));
98 static int math_tanh (lua_State *L) {
100 lua_pushcomplex(L, _LF(ctanh) (luaL_checkcomplex(L,1)));
102 lua_pushnumber(L, _LF(tanh) (luaL_checknumber(L, 1)));
107 static int math_asin (lua_State *L) {
109 lua_pushcomplex(L, _LF(casin) (luaL_checkcomplex(L,1)));
111 lua_pushnumber(L, _LF(asin) (luaL_checknumber(L, 1)));
116 static int math_acos (lua_State *L) {
118 lua_pushcomplex(L, _LF(cacos) (luaL_checkcomplex(L,1)));
120 lua_pushnumber(L, _LF(acos) (luaL_checknumber(L, 1)));
125 static int math_atan (lua_State *L) {
127 lua_pushcomplex(L, _LF(catan) (luaL_checkcomplex(L,1)));
129 lua_pushnumber(L, _LF(atan) (luaL_checknumber(L, 1)));
134 static int math_atan2 (lua_State *L) {
136 lua_pushnumber(L, _LF(atan2) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
140 static int math_ceil (lua_State *L) {
142 lua_Complex v= luaL_checkcomplex(L, 1);
143 lua_pushcomplex(L, _LF(ceil) (_LF(creal)(v)) + _LF(ceil) (_LF(cimag)(v))*I);
145 lua_pushnumber(L, _LF(ceil) (luaL_checknumber(L, 1)));
150 static int math_floor (lua_State *L) {
152 lua_Complex v= luaL_checkcomplex(L, 1);
153 lua_pushcomplex(L, _LF(floor) (_LF(creal)(v)) + _LF(floor) (_LF(cimag)(v))*I);
155 lua_pushnumber(L, _LF(floor) (luaL_checknumber(L, 1)));
160 static int math_fmod (lua_State *L) {
162 lua_pushnumber(L, _LF(fmod) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
166 static int math_modf (lua_State *L) {
169 lua_Number fp = _LF(modf) (luaL_checknumber(L, 1), &ip);
170 lua_pushnumber(L, ip);
171 lua_pushnumber(L, fp);
175 static int math_sqrt (lua_State *L) {
177 lua_pushcomplex(L, _LF(csqrt) (luaL_checkcomplex(L,1)));
179 lua_pushnumber(L, _LF(sqrt) (luaL_checknumber(L, 1)));
184 static int math_pow (lua_State *L) {
186 /* C99 'cpow' gives somewhat inaccurate results (i.e. (-1)^2 = -1+1.2246467991474e-16i).
187 * 'luai_vectpow' smoothens such, reusing it is the reason we need to #include "lnum.h".
189 lua_pushcomplex(L, luai_vectpow(luaL_checkcomplex(L,1), luaL_checkcomplex(L,2)));
191 lua_pushnumber(L, _LF(pow) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
196 static int math_log (lua_State *L) {
198 lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1)));
200 lua_pushnumber(L, _LF(log) (luaL_checknumber(L, 1)));
205 static int math_log10 (lua_State *L) {
207 /* Not in standard <complex.h> , but easy to calculate: log_a(x) = log_b(x) / log_b(a)
209 lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1)) / _LF(log) (10));
211 lua_pushnumber(L, _LF(log10) (luaL_checknumber(L, 1)));
216 static int math_exp (lua_State *L) {
218 lua_pushcomplex(L, _LF(cexp) (luaL_checkcomplex(L,1)));
220 lua_pushnumber(L, _LF(exp) (luaL_checknumber(L, 1)));
225 static int math_deg (lua_State *L) {
226 lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
230 static int math_rad (lua_State *L) {
231 lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
235 static int math_frexp (lua_State *L) {
237 lua_pushnumber(L, _LF(frexp) (luaL_checknumber(L, 1), &e));
238 lua_pushinteger(L, e);
242 static int math_ldexp (lua_State *L) {
243 lua_pushnumber(L, _LF(ldexp) (luaL_checknumber(L, 1), luaL_checkint(L, 2)));
249 static int math_min (lua_State *L) {
251 int n = lua_gettop(L); /* number of arguments */
252 lua_Number dmin = luaL_checknumber(L, 1);
254 for (i=2; i<=n; i++) {
255 lua_Number d = luaL_checknumber(L, i);
259 lua_pushnumber(L, dmin);
264 static int math_max (lua_State *L) {
266 int n = lua_gettop(L); /* number of arguments */
267 lua_Number dmax = luaL_checknumber(L, 1);
269 for (i=2; i<=n; i++) {
270 lua_Number d = luaL_checknumber(L, i);
274 lua_pushnumber(L, dmax);
279 static int math_random (lua_State *L) {
280 /* the `%' avoids the (rare) case of r==1, and is needed also because on
281 some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
282 lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
283 int n= lua_gettop(L); /* number of arguments */
284 if (n==0) { /* no arguments: range [0,1) */
285 lua_pushnumber(L, r);
286 } else if (n<=2) { /* int range [1,u] or [l,u] */
287 int l= n==1 ? 1 : luaL_checkint(L, 1);
288 int u = luaL_checkint(L, n);
291 luaL_argcheck(L, l<=u, n, "interval is empty");
292 d= _LF(floor)(r*(u-l+1));
293 lua_number2int(tmp,d);
294 lua_pushinteger(L, l+tmp);
296 return luaL_error(L, "wrong number of arguments");
302 static int math_randomseed (lua_State *L) {
303 srand(luaL_checkint(L, 1));
308 * Lua 5.1 does not have acosh, asinh, atanh for scalars (not ANSI C)
310 #if __STDC_VERSION__ >= 199901L
311 static int math_acosh (lua_State *L) {
313 lua_pushcomplex(L, _LF(cacosh) (luaL_checkcomplex(L,1)));
315 lua_pushnumber(L, _LF(acosh) (luaL_checknumber(L,1)));
319 static int math_asinh (lua_State *L) {
321 lua_pushcomplex(L, _LF(casinh) (luaL_checkcomplex(L,1)));
323 lua_pushnumber(L, _LF(asinh) (luaL_checknumber(L,1)));
327 static int math_atanh (lua_State *L) {
329 lua_pushcomplex(L, _LF(catanh) (luaL_checkcomplex(L,1)));
331 lua_pushnumber(L, _LF(atanh) (luaL_checknumber(L,1)));
338 * C99 complex functions, not covered above.
341 static int math_arg (lua_State *L) {
342 lua_pushnumber(L, _LF(carg) (luaL_checkcomplex(L,1)));
346 static int math_imag (lua_State *L) {
347 lua_pushnumber(L, _LF(cimag) (luaL_checkcomplex(L,1)));
351 static int math_real (lua_State *L) {
352 lua_pushnumber(L, _LF(creal) (luaL_checkcomplex(L,1)));
356 static int math_conj (lua_State *L) {
357 lua_pushcomplex(L, _LF(conj) (luaL_checkcomplex(L,1)));
361 static int math_proj (lua_State *L) {
362 lua_pushcomplex(L, _LF(cproj) (luaL_checkcomplex(L,1)));
368 static const luaL_Reg mathlib[] = {
372 {"atan2", math_atan2},
379 {"floor", math_floor},
381 {"frexp", math_frexp},
382 {"ldexp", math_ldexp},
383 {"log10", math_log10},
390 {"random", math_random},
391 {"randomseed", math_randomseed},
397 #if __STDC_VERSION__ >= 199901L
398 {"acosh", math_acosh},
399 {"asinh", math_asinh},
400 {"atanh", math_atanh},
416 LUALIB_API int luaopen_math (lua_State *L) {
417 luaL_register(L, LUA_MATHLIBNAME, mathlib);
418 lua_pushnumber(L, PI);
419 lua_setfield(L, -2, "pi");
420 lua_pushnumber(L, HUGE);
421 lua_setfield(L, -2, "huge");
422 lua_pushinteger(L, LUA_INTEGER_MAX );
423 lua_setfield(L, -2, "hugeint");
424 #if defined(LUA_COMPAT_MOD)
425 lua_getfield(L, -1, "fmod");
426 lua_setfield(L, -2, "mod");