]>
git.proxmox.com Git - ceph.git/blob - ceph/src/lua/src/lmathlib.c
2 ** $Id: lmathlib.c,v 1.117 2015/10/02 15:39:23 roberto Exp $
3 ** Standard mathematical library
4 ** See Copyright Notice in lua.h
23 #define PI (l_mathop(3.141592653589793238462643383279502884))
26 #if !defined(l_rand) /* { */
27 #if defined(LUA_USE_POSIX)
28 #define l_rand() random()
29 #define l_srand(x) srandom(x)
30 #define L_RANDMAX 2147483647 /* (2^31 - 1), following POSIX */
32 #define l_rand() rand()
33 #define l_srand(x) srand(x)
34 #define L_RANDMAX RAND_MAX
39 static int math_abs (lua_State
*L
) {
40 if (lua_isinteger(L
, 1)) {
41 lua_Integer n
= lua_tointeger(L
, 1);
42 if (n
< 0) n
= (lua_Integer
)(0u - (lua_Unsigned
)n
);
43 lua_pushinteger(L
, n
);
46 lua_pushnumber(L
, l_mathop(fabs
)(luaL_checknumber(L
, 1)));
50 static int math_sin (lua_State
*L
) {
51 lua_pushnumber(L
, l_mathop(sin
)(luaL_checknumber(L
, 1)));
55 static int math_cos (lua_State
*L
) {
56 lua_pushnumber(L
, l_mathop(cos
)(luaL_checknumber(L
, 1)));
60 static int math_tan (lua_State
*L
) {
61 lua_pushnumber(L
, l_mathop(tan
)(luaL_checknumber(L
, 1)));
65 static int math_asin (lua_State
*L
) {
66 lua_pushnumber(L
, l_mathop(asin
)(luaL_checknumber(L
, 1)));
70 static int math_acos (lua_State
*L
) {
71 lua_pushnumber(L
, l_mathop(acos
)(luaL_checknumber(L
, 1)));
75 static int math_atan (lua_State
*L
) {
76 lua_Number y
= luaL_checknumber(L
, 1);
77 lua_Number x
= luaL_optnumber(L
, 2, 1);
78 lua_pushnumber(L
, l_mathop(atan2
)(y
, x
));
83 static int math_toint (lua_State
*L
) {
85 lua_Integer n
= lua_tointegerx(L
, 1, &valid
);
87 lua_pushinteger(L
, n
);
90 lua_pushnil(L
); /* value is not convertible to integer */
96 static void pushnumint (lua_State
*L
, lua_Number d
) {
98 if (lua_numbertointeger(d
, &n
)) /* does 'd' fit in an integer? */
99 lua_pushinteger(L
, n
); /* result is integer */
101 lua_pushnumber(L
, d
); /* result is float */
105 static int math_floor (lua_State
*L
) {
106 if (lua_isinteger(L
, 1))
107 lua_settop(L
, 1); /* integer is its own floor */
109 lua_Number d
= l_mathop(floor
)(luaL_checknumber(L
, 1));
116 static int math_ceil (lua_State
*L
) {
117 if (lua_isinteger(L
, 1))
118 lua_settop(L
, 1); /* integer is its own ceil */
120 lua_Number d
= l_mathop(ceil
)(luaL_checknumber(L
, 1));
127 static int math_fmod (lua_State
*L
) {
128 if (lua_isinteger(L
, 1) && lua_isinteger(L
, 2)) {
129 lua_Integer d
= lua_tointeger(L
, 2);
130 if ((lua_Unsigned
)d
+ 1u <= 1u) { /* special cases: -1 or 0 */
131 luaL_argcheck(L
, d
!= 0, 2, "zero");
132 lua_pushinteger(L
, 0); /* avoid overflow with 0x80000... / -1 */
135 lua_pushinteger(L
, lua_tointeger(L
, 1) % d
);
138 lua_pushnumber(L
, l_mathop(fmod
)(luaL_checknumber(L
, 1),
139 luaL_checknumber(L
, 2)));
145 ** next function does not use 'modf', avoiding problems with 'double*'
146 ** (which is not compatible with 'float*') when lua_Number is not
149 static int math_modf (lua_State
*L
) {
150 if (lua_isinteger(L
,1)) {
151 lua_settop(L
, 1); /* number is its own integer part */
152 lua_pushnumber(L
, 0); /* no fractional part */
155 lua_Number n
= luaL_checknumber(L
, 1);
156 /* integer part (rounds toward zero) */
157 lua_Number ip
= (n
< 0) ? l_mathop(ceil
)(n
) : l_mathop(floor
)(n
);
159 /* fractional part (test needed for inf/-inf) */
160 lua_pushnumber(L
, (n
== ip
) ? l_mathop(0.0) : (n
- ip
));
166 static int math_sqrt (lua_State
*L
) {
167 lua_pushnumber(L
, l_mathop(sqrt
)(luaL_checknumber(L
, 1)));
172 static int math_ult (lua_State
*L
) {
173 lua_Integer a
= luaL_checkinteger(L
, 1);
174 lua_Integer b
= luaL_checkinteger(L
, 2);
175 lua_pushboolean(L
, (lua_Unsigned
)a
< (lua_Unsigned
)b
);
179 static int math_log (lua_State
*L
) {
180 lua_Number x
= luaL_checknumber(L
, 1);
182 if (lua_isnoneornil(L
, 2))
183 res
= l_mathop(log
)(x
);
185 lua_Number base
= luaL_checknumber(L
, 2);
186 #if !defined(LUA_USE_C89)
187 if (base
== 2.0) res
= l_mathop(log2
)(x
); else
189 if (base
== 10.0) res
= l_mathop(log10
)(x
);
190 else res
= l_mathop(log
)(x
)/l_mathop(log
)(base
);
192 lua_pushnumber(L
, res
);
196 static int math_exp (lua_State
*L
) {
197 lua_pushnumber(L
, l_mathop(exp
)(luaL_checknumber(L
, 1)));
201 static int math_deg (lua_State
*L
) {
202 lua_pushnumber(L
, luaL_checknumber(L
, 1) * (l_mathop(180.0) / PI
));
206 static int math_rad (lua_State
*L
) {
207 lua_pushnumber(L
, luaL_checknumber(L
, 1) * (PI
/ l_mathop(180.0)));
212 static int math_min (lua_State
*L
) {
213 int n
= lua_gettop(L
); /* number of arguments */
214 int imin
= 1; /* index of current minimum value */
216 luaL_argcheck(L
, n
>= 1, 1, "value expected");
217 for (i
= 2; i
<= n
; i
++) {
218 if (lua_compare(L
, i
, imin
, LUA_OPLT
))
221 lua_pushvalue(L
, imin
);
226 static int math_max (lua_State
*L
) {
227 int n
= lua_gettop(L
); /* number of arguments */
228 int imax
= 1; /* index of current maximum value */
230 luaL_argcheck(L
, n
>= 1, 1, "value expected");
231 for (i
= 2; i
<= n
; i
++) {
232 if (lua_compare(L
, imax
, i
, LUA_OPLT
))
235 lua_pushvalue(L
, imax
);
240 ** This function uses 'double' (instead of 'lua_Number') to ensure that
241 ** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0'
242 ** will keep full precision (ensuring that 'r' is always less than 1.0.)
244 static int math_random (lua_State
*L
) {
246 double r
= (double)l_rand() * (1.0 / ((double)L_RANDMAX
+ 1.0));
247 switch (lua_gettop(L
)) { /* check number of arguments */
248 case 0: { /* no arguments */
249 lua_pushnumber(L
, (lua_Number
)r
); /* Number between 0 and 1 */
252 case 1: { /* only upper limit */
254 up
= luaL_checkinteger(L
, 1);
257 case 2: { /* lower and upper limits */
258 low
= luaL_checkinteger(L
, 1);
259 up
= luaL_checkinteger(L
, 2);
262 default: return luaL_error(L
, "wrong number of arguments");
264 /* random integer in the interval [low, up] */
265 luaL_argcheck(L
, low
<= up
, 1, "interval is empty");
266 luaL_argcheck(L
, low
>= 0 || up
<= LUA_MAXINTEGER
+ low
, 1,
267 "interval too large");
268 r
*= (double)(up
- low
) + 1.0;
269 lua_pushinteger(L
, (lua_Integer
)r
+ low
);
274 static int math_randomseed (lua_State
*L
) {
275 l_srand((unsigned int)(lua_Integer
)luaL_checknumber(L
, 1));
276 (void)l_rand(); /* discard first value to avoid undesirable correlations */
281 static int math_type (lua_State
*L
) {
282 if (lua_type(L
, 1) == LUA_TNUMBER
) {
283 if (lua_isinteger(L
, 1))
284 lua_pushliteral(L
, "integer");
286 lua_pushliteral(L
, "float");
297 ** {==================================================================
298 ** Deprecated functions (for compatibility only)
299 ** ===================================================================
301 #if defined(LUA_COMPAT_MATHLIB)
303 static int math_cosh (lua_State
*L
) {
304 lua_pushnumber(L
, l_mathop(cosh
)(luaL_checknumber(L
, 1)));
308 static int math_sinh (lua_State
*L
) {
309 lua_pushnumber(L
, l_mathop(sinh
)(luaL_checknumber(L
, 1)));
313 static int math_tanh (lua_State
*L
) {
314 lua_pushnumber(L
, l_mathop(tanh
)(luaL_checknumber(L
, 1)));
318 static int math_pow (lua_State
*L
) {
319 lua_Number x
= luaL_checknumber(L
, 1);
320 lua_Number y
= luaL_checknumber(L
, 2);
321 lua_pushnumber(L
, l_mathop(pow
)(x
, y
));
325 static int math_frexp (lua_State
*L
) {
327 lua_pushnumber(L
, l_mathop(frexp
)(luaL_checknumber(L
, 1), &e
));
328 lua_pushinteger(L
, e
);
332 static int math_ldexp (lua_State
*L
) {
333 lua_Number x
= luaL_checknumber(L
, 1);
334 int ep
= (int)luaL_checkinteger(L
, 2);
335 lua_pushnumber(L
, l_mathop(ldexp
)(x
, ep
));
339 static int math_log10 (lua_State
*L
) {
340 lua_pushnumber(L
, l_mathop(log10
)(luaL_checknumber(L
, 1)));
345 /* }================================================================== */
349 static const luaL_Reg mathlib
[] = {
358 {"tointeger", math_toint
},
359 {"floor", math_floor
},
367 {"random", math_random
},
368 {"randomseed", math_randomseed
},
373 #if defined(LUA_COMPAT_MATHLIB)
374 {"atan2", math_atan
},
379 {"frexp", math_frexp
},
380 {"ldexp", math_ldexp
},
381 {"log10", math_log10
},
386 {"maxinteger", NULL
},
387 {"mininteger", NULL
},
395 LUAMOD_API
int luaopen_math (lua_State
*L
) {
396 luaL_newlib(L
, mathlib
);
397 lua_pushnumber(L
, PI
);
398 lua_setfield(L
, -2, "pi");
399 lua_pushnumber(L
, (lua_Number
)HUGE_VAL
);
400 lua_setfield(L
, -2, "huge");
401 lua_pushinteger(L
, LUA_MAXINTEGER
);
402 lua_setfield(L
, -2, "maxinteger");
403 lua_pushinteger(L
, LUA_MININTEGER
);
404 lua_setfield(L
, -2, "mininteger");