1 /* $NetBSD: lmathlib.c,v 1.4 2015/10/08 13:21:00 mbalmer Exp $ */
4 ** Id: lmathlib.c,v 1.115 2015/03/12 14:04:04 roberto Exp
5 ** Standard mathematical library
6 ** See Copyright Notice in lua.h
25 #define PI (l_mathop(3.141592653589793238462643383279502884))
28 #if !defined(l_rand) /* { */
29 #if defined(LUA_USE_POSIX)
30 #define l_rand() random()
31 #define l_srand(x) srandom(x)
32 #define L_RANDMAX 2147483647 /* (2^31 - 1), following POSIX */
34 #define l_rand() rand()
35 #define l_srand(x) srand(x)
36 #define L_RANDMAX RAND_MAX
41 static int math_abs (lua_State
*L
) {
42 if (lua_isinteger(L
, 1)) {
43 lua_Integer n
= lua_tointeger(L
, 1);
44 if (n
< 0) n
= (lua_Integer
)(0u - n
);
45 lua_pushinteger(L
, n
);
48 lua_pushnumber(L
, l_mathop(fabs
)(luaL_checknumber(L
, 1)));
52 static int math_sin (lua_State
*L
) {
53 lua_pushnumber(L
, l_mathop(sin
)(luaL_checknumber(L
, 1)));
57 static int math_cos (lua_State
*L
) {
58 lua_pushnumber(L
, l_mathop(cos
)(luaL_checknumber(L
, 1)));
62 static int math_tan (lua_State
*L
) {
63 lua_pushnumber(L
, l_mathop(tan
)(luaL_checknumber(L
, 1)));
67 static int math_asin (lua_State
*L
) {
68 lua_pushnumber(L
, l_mathop(asin
)(luaL_checknumber(L
, 1)));
72 static int math_acos (lua_State
*L
) {
73 lua_pushnumber(L
, l_mathop(acos
)(luaL_checknumber(L
, 1)));
77 static int math_atan (lua_State
*L
) {
78 lua_Number y
= luaL_checknumber(L
, 1);
79 lua_Number x
= luaL_optnumber(L
, 2, 1);
80 lua_pushnumber(L
, l_mathop(atan2
)(y
, x
));
85 static int math_toint (lua_State
*L
) {
87 lua_Integer n
= lua_tointegerx(L
, 1, &valid
);
89 lua_pushinteger(L
, n
);
92 lua_pushnil(L
); /* value is not convertible to integer */
98 static void pushnumint (lua_State
*L
, lua_Number d
) {
100 if (lua_numbertointeger(d
, &n
)) /* does 'd' fit in an integer? */
101 lua_pushinteger(L
, n
); /* result is integer */
103 lua_pushnumber(L
, d
); /* result is float */
107 static int math_floor (lua_State
*L
) {
108 if (lua_isinteger(L
, 1))
109 lua_settop(L
, 1); /* integer is its own floor */
111 lua_Number d
= l_mathop(floor
)(luaL_checknumber(L
, 1));
118 static int math_ceil (lua_State
*L
) {
119 if (lua_isinteger(L
, 1))
120 lua_settop(L
, 1); /* integer is its own ceil */
122 lua_Number d
= l_mathop(ceil
)(luaL_checknumber(L
, 1));
129 static int math_fmod (lua_State
*L
) {
130 if (lua_isinteger(L
, 1) && lua_isinteger(L
, 2)) {
131 lua_Integer d
= lua_tointeger(L
, 2);
132 if ((lua_Unsigned
)d
+ 1u <= 1u) { /* special cases: -1 or 0 */
133 luaL_argcheck(L
, d
!= 0, 2, "zero");
134 lua_pushinteger(L
, 0); /* avoid overflow with 0x80000... / -1 */
137 lua_pushinteger(L
, lua_tointeger(L
, 1) % d
);
140 lua_pushnumber(L
, l_mathop(fmod
)(luaL_checknumber(L
, 1),
141 luaL_checknumber(L
, 2)));
147 ** next function does not use 'modf', avoiding problems with 'double*'
148 ** (which is not compatible with 'float*') when lua_Number is not
151 static int math_modf (lua_State
*L
) {
152 if (lua_isinteger(L
,1)) {
153 lua_settop(L
, 1); /* number is its own integer part */
154 lua_pushnumber(L
, 0); /* no fractional part */
157 lua_Number n
= luaL_checknumber(L
, 1);
158 /* integer part (rounds toward zero) */
159 lua_Number ip
= (n
< 0) ? l_mathop(ceil
)(n
) : l_mathop(floor
)(n
);
161 /* fractional part (test needed for inf/-inf) */
162 lua_pushnumber(L
, (n
== ip
) ? l_mathop(0.0) : (n
- ip
));
168 static int math_sqrt (lua_State
*L
) {
169 lua_pushnumber(L
, l_mathop(sqrt
)(luaL_checknumber(L
, 1)));
174 static int math_ult (lua_State
*L
) {
175 lua_Integer a
= luaL_checkinteger(L
, 1);
176 lua_Integer b
= luaL_checkinteger(L
, 2);
177 lua_pushboolean(L
, (lua_Unsigned
)a
< (lua_Unsigned
)b
);
181 static int math_log (lua_State
*L
) {
182 lua_Number x
= luaL_checknumber(L
, 1);
184 if (lua_isnoneornil(L
, 2))
185 res
= l_mathop(log
)(x
);
187 lua_Number base
= luaL_checknumber(L
, 2);
188 #if !defined(LUA_USE_C89)
189 if (base
== 2.0) res
= l_mathop(log2
)(x
); else
191 if (base
== 10.0) res
= l_mathop(log10
)(x
);
192 else res
= l_mathop(log
)(x
)/l_mathop(log
)(base
);
194 lua_pushnumber(L
, res
);
198 static int math_exp (lua_State
*L
) {
199 lua_pushnumber(L
, l_mathop(exp
)(luaL_checknumber(L
, 1)));
203 static int math_deg (lua_State
*L
) {
204 lua_pushnumber(L
, luaL_checknumber(L
, 1) * (l_mathop(180.0) / PI
));
208 static int math_rad (lua_State
*L
) {
209 lua_pushnumber(L
, luaL_checknumber(L
, 1) * (PI
/ l_mathop(180.0)));
214 static int math_min (lua_State
*L
) {
215 int n
= lua_gettop(L
); /* number of arguments */
216 int imin
= 1; /* index of current minimum value */
218 luaL_argcheck(L
, n
>= 1, 1, "value expected");
219 for (i
= 2; i
<= n
; i
++) {
220 if (lua_compare(L
, i
, imin
, LUA_OPLT
))
223 lua_pushvalue(L
, imin
);
228 static int math_max (lua_State
*L
) {
229 int n
= lua_gettop(L
); /* number of arguments */
230 int imax
= 1; /* index of current maximum value */
232 luaL_argcheck(L
, n
>= 1, 1, "value expected");
233 for (i
= 2; i
<= n
; i
++) {
234 if (lua_compare(L
, imax
, i
, LUA_OPLT
))
237 lua_pushvalue(L
, imax
);
242 ** This function uses 'double' (instead of 'lua_Number') to ensure that
243 ** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0'
244 ** will keep full precision (ensuring that 'r' is always less than 1.0.)
246 static int math_random (lua_State
*L
) {
248 double r
= (double)l_rand() * (1.0 / ((double)L_RANDMAX
+ 1.0));
249 switch (lua_gettop(L
)) { /* check number of arguments */
250 case 0: { /* no arguments */
251 lua_pushnumber(L
, (lua_Number
)r
); /* Number between 0 and 1 */
254 case 1: { /* only upper limit */
256 up
= luaL_checkinteger(L
, 1);
259 case 2: { /* lower and upper limits */
260 low
= luaL_checkinteger(L
, 1);
261 up
= luaL_checkinteger(L
, 2);
264 default: return luaL_error(L
, "wrong number of arguments");
266 /* random integer in the interval [low, up] */
267 luaL_argcheck(L
, low
<= up
, 1, "interval is empty");
268 luaL_argcheck(L
, low
>= 0 || up
<= LUA_MAXINTEGER
+ low
, 1,
269 "interval too large");
270 r
*= (double)(up
- low
) + 1.0;
271 lua_pushinteger(L
, (lua_Integer
)r
+ low
);
276 static int math_randomseed (lua_State
*L
) {
277 l_srand((unsigned int)(lua_Integer
)luaL_checknumber(L
, 1));
278 (void)rand(); /* discard first value to avoid undesirable correlations */
283 static int math_type (lua_State
*L
) {
284 if (lua_type(L
, 1) == LUA_TNUMBER
) {
285 if (lua_isinteger(L
, 1))
286 lua_pushliteral(L
, "integer");
288 lua_pushliteral(L
, "float");
299 ** {==================================================================
300 ** Deprecated functions (for compatibility only)
301 ** ===================================================================
303 #if defined(LUA_COMPAT_MATHLIB)
305 static int math_cosh (lua_State
*L
) {
306 lua_pushnumber(L
, l_mathop(cosh
)(luaL_checknumber(L
, 1)));
310 static int math_sinh (lua_State
*L
) {
311 lua_pushnumber(L
, l_mathop(sinh
)(luaL_checknumber(L
, 1)));
315 static int math_tanh (lua_State
*L
) {
316 lua_pushnumber(L
, l_mathop(tanh
)(luaL_checknumber(L
, 1)));
320 static int math_pow (lua_State
*L
) {
321 lua_Number x
= luaL_checknumber(L
, 1);
322 lua_Number y
= luaL_checknumber(L
, 2);
323 lua_pushnumber(L
, l_mathop(pow
)(x
, y
));
327 static int math_frexp (lua_State
*L
) {
329 lua_pushnumber(L
, l_mathop(frexp
)(luaL_checknumber(L
, 1), &e
));
330 lua_pushinteger(L
, e
);
334 static int math_ldexp (lua_State
*L
) {
335 lua_Number x
= luaL_checknumber(L
, 1);
336 int ep
= (int)luaL_checkinteger(L
, 2);
337 lua_pushnumber(L
, l_mathop(ldexp
)(x
, ep
));
341 static int math_log10 (lua_State
*L
) {
342 lua_pushnumber(L
, l_mathop(log10
)(luaL_checknumber(L
, 1)));
347 /* }================================================================== */
351 static const luaL_Reg mathlib
[] = {
360 {"tointeger", math_toint
},
361 {"floor", math_floor
},
369 {"random", math_random
},
370 {"randomseed", math_randomseed
},
375 #if defined(LUA_COMPAT_MATHLIB)
376 {"atan2", math_atan
},
381 {"frexp", math_frexp
},
382 {"ldexp", math_ldexp
},
383 {"log10", math_log10
},
388 {"maxinteger", NULL
},
389 {"mininteger", NULL
},
397 LUAMOD_API
int luaopen_math (lua_State
*L
) {
398 luaL_newlib(L
, mathlib
);
399 lua_pushnumber(L
, PI
);
400 lua_setfield(L
, -2, "pi");
401 lua_pushnumber(L
, (lua_Number
)HUGE_VAL
);
402 lua_setfield(L
, -2, "huge");
403 lua_pushinteger(L
, LUA_MAXINTEGER
);
404 lua_setfield(L
, -2, "maxinteger");
405 lua_pushinteger(L
, LUA_MININTEGER
);
406 lua_setfield(L
, -2, "mininteger");