2 ** $Id: lmathlib.c,v 1.32 2000/10/31 13:10:24 roberto Exp $
3 ** Standard mathematical library
4 ** See Copyright Notice in lua.h
18 #define PI (3.14159265358979323846)
19 #define RADIANS_PER_DEGREE (PI/180.0)
24 ** If you want Lua to operate in radians (instead of degrees),
28 #define FROMRAD(a) (a)
31 #define FROMRAD(a) ((a)/RADIANS_PER_DEGREE)
32 #define TORAD(a) ((a)*RADIANS_PER_DEGREE)
36 static int math_abs (lua_State
*L
) {
37 lua_pushnumber(L
, fabs(luaL_check_number(L
, 1)));
41 static int math_sin (lua_State
*L
) {
42 lua_pushnumber(L
, sin(TORAD(luaL_check_number(L
, 1))));
46 static int math_cos (lua_State
*L
) {
47 lua_pushnumber(L
, cos(TORAD(luaL_check_number(L
, 1))));
51 static int math_tan (lua_State
*L
) {
52 lua_pushnumber(L
, tan(TORAD(luaL_check_number(L
, 1))));
56 static int math_asin (lua_State
*L
) {
57 lua_pushnumber(L
, FROMRAD(asin(luaL_check_number(L
, 1))));
61 static int math_acos (lua_State
*L
) {
62 lua_pushnumber(L
, FROMRAD(acos(luaL_check_number(L
, 1))));
66 static int math_atan (lua_State
*L
) {
67 lua_pushnumber(L
, FROMRAD(atan(luaL_check_number(L
, 1))));
71 static int math_atan2 (lua_State
*L
) {
72 lua_pushnumber(L
, FROMRAD(atan2(luaL_check_number(L
, 1), luaL_check_number(L
, 2))));
76 static int math_ceil (lua_State
*L
) {
77 lua_pushnumber(L
, ceil(luaL_check_number(L
, 1)));
81 static int math_floor (lua_State
*L
) {
82 lua_pushnumber(L
, floor(luaL_check_number(L
, 1)));
86 static int math_mod (lua_State
*L
) {
87 lua_pushnumber(L
, fmod(luaL_check_number(L
, 1), luaL_check_number(L
, 2)));
91 static int math_sqrt (lua_State
*L
) {
92 lua_pushnumber(L
, sqrt(luaL_check_number(L
, 1)));
96 static int math_pow (lua_State
*L
) {
97 lua_pushnumber(L
, pow(luaL_check_number(L
, 1), luaL_check_number(L
, 2)));
101 static int math_log (lua_State
*L
) {
102 lua_pushnumber(L
, log(luaL_check_number(L
, 1)));
106 static int math_log10 (lua_State
*L
) {
107 lua_pushnumber(L
, log10(luaL_check_number(L
, 1)));
111 static int math_exp (lua_State
*L
) {
112 lua_pushnumber(L
, exp(luaL_check_number(L
, 1)));
116 static int math_deg (lua_State
*L
) {
117 lua_pushnumber(L
, luaL_check_number(L
, 1)/RADIANS_PER_DEGREE
);
121 static int math_rad (lua_State
*L
) {
122 lua_pushnumber(L
, luaL_check_number(L
, 1)*RADIANS_PER_DEGREE
);
126 static int math_frexp (lua_State
*L
) {
128 lua_pushnumber(L
, frexp(luaL_check_number(L
, 1), &e
));
129 lua_pushnumber(L
, e
);
133 static int math_ldexp (lua_State
*L
) {
134 lua_pushnumber(L
, ldexp(luaL_check_number(L
, 1), luaL_check_int(L
, 2)));
140 static int math_min (lua_State
*L
) {
141 int n
= lua_gettop(L
); /* number of arguments */
142 double dmin
= luaL_check_number(L
, 1);
144 for (i
=2; i
<=n
; i
++) {
145 double d
= luaL_check_number(L
, i
);
149 lua_pushnumber(L
, dmin
);
154 static int math_max (lua_State
*L
) {
155 int n
= lua_gettop(L
); /* number of arguments */
156 double dmax
= luaL_check_number(L
, 1);
158 for (i
=2; i
<=n
; i
++) {
159 double d
= luaL_check_number(L
, i
);
163 lua_pushnumber(L
, dmax
);
168 static int math_random (lua_State
*L
) {
169 /* the '%' avoids the (rare) case of r==1, and is needed also because on
170 some systems (SunOS!) "rand()" may return a value larger than RAND_MAX */
171 double r
= (double)(rand()%RAND_MAX
) / (double)RAND_MAX
;
172 switch (lua_gettop(L
)) { /* check number of arguments */
173 case 0: { /* no arguments */
174 lua_pushnumber(L
, r
); /* Number between 0 and 1 */
177 case 1: { /* only upper limit */
178 int u
= luaL_check_int(L
, 1);
179 luaL_arg_check(L
, 1<=u
, 1, "interval is empty");
180 lua_pushnumber(L
, (int)(r
*u
)+1); /* integer between 1 and `u' */
183 case 2: { /* lower and upper limits */
184 int l
= luaL_check_int(L
, 1);
185 int u
= luaL_check_int(L
, 2);
186 luaL_arg_check(L
, l
<=u
, 2, "interval is empty");
187 lua_pushnumber(L
, (int)(r
*(u
-l
+1))+l
); /* integer between `l' and `u' */
190 default: lua_error(L
, "wrong number of arguments");
196 static int math_randomseed (lua_State
*L
) {
197 srand(luaL_check_int(L
, 1));
202 static const struct luaL_reg mathlib
[] = {
210 {"atan2", math_atan2
},
212 {"floor", math_floor
},
214 {"frexp", math_frexp
},
215 {"ldexp", math_ldexp
},
220 {"log10", math_log10
},
224 {"random", math_random
},
225 {"randomseed", math_randomseed
}
231 LUALIB_API
void lua_mathlibopen (lua_State
*L
) {
232 luaL_openl(L
, mathlib
);
233 lua_pushcfunction(L
, math_pow
);
234 lua_settagmethod(L
, LUA_TNUMBER
, "pow");
235 lua_pushnumber(L
, PI
);
236 lua_setglobal(L
, "PI");