Line data Source code
1 : /*
2 : ** $Id: lmathlib.c,v 1.119.1.1 2017/04/19 17:20:42 roberto Exp $
3 : ** Standard mathematical library
4 : ** See Copyright Notice in lua.h
5 : */
6 :
7 : #define lmathlib_c
8 : #define LUA_LIB
9 :
10 : #include "lprefix.h"
11 :
12 :
13 : #include <stdlib.h>
14 : #include <math.h>
15 :
16 : #include "lua.h"
17 :
18 : #include "lauxlib.h"
19 : #include "lualib.h"
20 :
21 : #if defined(ARDUPILOT_BUILD)
22 : #pragma GCC diagnostic ignored "-Wfloat-equal"
23 : #endif
24 :
25 :
26 : #undef PI
27 : #define PI (l_mathop(3.141592653589793238462643383279502884))
28 :
29 :
30 : #if !defined(l_rand) /* { */
31 : #if defined(LUA_USE_POSIX)
32 : #define l_rand() random()
33 : #define l_srand(x) srandom(x)
34 : #define L_RANDMAX 2147483647 /* (2^31 - 1), following POSIX */
35 : #else
36 : #define l_rand() rand()
37 : #define l_srand(x) srand(x)
38 : #define L_RANDMAX RAND_MAX
39 : #endif
40 : #endif /* } */
41 :
42 :
43 175458 : static int math_abs (lua_State *L) {
44 175458 : if (lua_isinteger(L, 1)) {
45 18697 : lua_Integer n = lua_tointeger(L, 1);
46 18697 : if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n);
47 18697 : lua_pushinteger(L, n);
48 : }
49 : else
50 156761 : lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
51 175458 : return 1;
52 : }
53 :
54 33756 : static int math_sin (lua_State *L) {
55 33756 : lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
56 33756 : return 1;
57 : }
58 :
59 57198 : static int math_cos (lua_State *L) {
60 57198 : lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
61 57198 : return 1;
62 : }
63 :
64 1 : static int math_tan (lua_State *L) {
65 1 : lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
66 1 : return 1;
67 : }
68 :
69 1 : static int math_asin (lua_State *L) {
70 1 : lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
71 1 : return 1;
72 : }
73 :
74 1 : static int math_acos (lua_State *L) {
75 1 : lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
76 1 : return 1;
77 : }
78 :
79 1395 : static int math_atan (lua_State *L) {
80 1395 : lua_Number y = luaL_checknumber(L, 1);
81 1395 : lua_Number x = luaL_optnumber(L, 2, 1);
82 1395 : lua_pushnumber(L, l_mathop(atan2)(y, x));
83 1395 : return 1;
84 : }
85 :
86 :
87 18 : static int math_toint (lua_State *L) {
88 : int valid;
89 18 : lua_Integer n = lua_tointegerx(L, 1, &valid);
90 18 : if (valid)
91 8 : lua_pushinteger(L, n);
92 : else {
93 10 : luaL_checkany(L, 1);
94 10 : lua_pushnil(L); /* value is not convertible to integer */
95 : }
96 18 : return 1;
97 : }
98 :
99 :
100 32049 : static void pushnumint (lua_State *L, lua_Number d) {
101 : lua_Integer n;
102 32049 : if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */
103 32015 : lua_pushinteger(L, n); /* result is integer */
104 : else
105 34 : lua_pushnumber(L, d); /* result is float */
106 32049 : }
107 :
108 :
109 32023 : static int math_floor (lua_State *L) {
110 32023 : if (lua_isinteger(L, 1))
111 2 : lua_settop(L, 1); /* integer is its own floor */
112 : else {
113 32021 : lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1));
114 32020 : pushnumint(L, d);
115 : }
116 32022 : return 1;
117 : }
118 :
119 :
120 18 : static int math_ceil (lua_State *L) {
121 18 : if (lua_isinteger(L, 1))
122 2 : lua_settop(L, 1); /* integer is its own ceil */
123 : else {
124 16 : lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1));
125 15 : pushnumint(L, d);
126 : }
127 17 : return 1;
128 : }
129 :
130 :
131 49899 : static int math_fmod (lua_State *L) {
132 50060 : if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) {
133 162 : lua_Integer d = lua_tointeger(L, 2);
134 162 : if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */
135 14 : luaL_argcheck(L, d != 0, 2, "zero");
136 13 : lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */
137 : }
138 : else
139 148 : lua_pushinteger(L, lua_tointeger(L, 1) % d);
140 : }
141 : else
142 49737 : lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
143 : luaL_checknumber(L, 2)));
144 49898 : return 1;
145 : }
146 :
147 :
148 : /*
149 : ** next function does not use 'modf', avoiding problems with 'double*'
150 : ** (which is not compatible with 'float*') when lua_Number is not
151 : ** 'double'.
152 : */
153 18 : static int math_modf (lua_State *L) {
154 18 : if (lua_isinteger(L ,1)) {
155 4 : lua_settop(L, 1); /* number is its own integer part */
156 4 : lua_pushnumber(L, 0); /* no fractional part */
157 : }
158 : else {
159 14 : lua_Number n = luaL_checknumber(L, 1);
160 : /* integer part (rounds toward zero) */
161 14 : lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n);
162 14 : pushnumint(L, ip);
163 : /* fractional part (test needed for inf/-inf) */
164 14 : lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip));
165 : }
166 18 : return 2;
167 : }
168 :
169 :
170 18772 : static int math_sqrt (lua_State *L) {
171 18772 : lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
172 18772 : return 1;
173 : }
174 :
175 :
176 7 : static int math_ult (lua_State *L) {
177 7 : lua_Integer a = luaL_checkinteger(L, 1);
178 7 : lua_Integer b = luaL_checkinteger(L, 2);
179 7 : lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b);
180 7 : return 1;
181 : }
182 :
183 19440 : static int math_log (lua_State *L) {
184 19440 : lua_Number x = luaL_checknumber(L, 1);
185 : lua_Number res;
186 19440 : if (lua_isnoneornil(L, 2))
187 19435 : res = l_mathop(log)(x);
188 : else {
189 5 : lua_Number base = luaL_checknumber(L, 2);
190 : #if !defined(LUA_USE_C89)
191 5 : if (base == l_mathop(2.0))
192 3 : res = l_mathop(log2)(x); else
193 : #endif
194 2 : if (base == l_mathop(10.0))
195 1 : res = l_mathop(log10)(x);
196 : else
197 1 : res = l_mathop(log)(x)/l_mathop(log)(base);
198 : }
199 19440 : lua_pushnumber(L, res);
200 19440 : return 1;
201 : }
202 :
203 2820 : static int math_exp (lua_State *L) {
204 2820 : lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
205 2820 : return 1;
206 : }
207 :
208 97406 : static int math_deg (lua_State *L) {
209 97406 : lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI));
210 97406 : return 1;
211 : }
212 :
213 57277 : static int math_rad (lua_State *L) {
214 57277 : lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0)));
215 57277 : return 1;
216 : }
217 :
218 :
219 5272 : static int math_min (lua_State *L) {
220 5272 : int n = lua_gettop(L); /* number of arguments */
221 5272 : int imin = 1; /* index of current minimum value */
222 : int i;
223 5272 : luaL_argcheck(L, n >= 1, 1, "value expected");
224 10547 : for (i = 2; i <= n; i++) {
225 5276 : if (lua_compare(L, i, imin, LUA_OPLT))
226 1807 : imin = i;
227 : }
228 5271 : lua_pushvalue(L, imin);
229 5271 : return 1;
230 : }
231 :
232 :
233 49847 : static int math_max (lua_State *L) {
234 49847 : int n = lua_gettop(L); /* number of arguments */
235 49847 : int imax = 1; /* index of current maximum value */
236 : int i;
237 49847 : luaL_argcheck(L, n >= 1, 1, "value expected");
238 99693 : for (i = 2; i <= n; i++) {
239 49847 : if (lua_compare(L, imax, i, LUA_OPLT))
240 43685 : imax = i;
241 : }
242 49846 : lua_pushvalue(L, imax);
243 49846 : return 1;
244 : }
245 :
246 : /*
247 : ** This function uses 'double' (instead of 'lua_Number') to ensure that
248 : ** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0'
249 : ** will keep full precision (ensuring that 'r' is always less than 1.0.)
250 : */
251 52196 : static int math_random (lua_State *L) {
252 : lua_Integer low, up;
253 52196 : double r = (double)l_rand() * (1.0 / ((double)L_RANDMAX + 1.0));
254 52196 : switch (lua_gettop(L)) { /* check number of arguments */
255 51061 : case 0: { /* no arguments */
256 51061 : lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */
257 51061 : return 1;
258 : }
259 107 : case 1: { /* only upper limit */
260 107 : low = 1;
261 107 : up = luaL_checkinteger(L, 1);
262 107 : break;
263 : }
264 1027 : case 2: { /* lower and upper limits */
265 1027 : low = luaL_checkinteger(L, 1);
266 1027 : up = luaL_checkinteger(L, 2);
267 1027 : break;
268 : }
269 1 : default: return luaL_error(L, "wrong number of arguments");
270 : }
271 : /* random integer in the interval [low, up] */
272 1134 : luaL_argcheck(L, low <= up, 1, "interval is empty");
273 1131 : luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1,
274 : "interval too large");
275 1128 : r *= (double)(up - low) + 1.0;
276 1128 : lua_pushinteger(L, (lua_Integer)r + low);
277 1128 : return 1;
278 : }
279 :
280 :
281 1 : static int math_randomseed (lua_State *L) {
282 1 : l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1));
283 1 : (void)l_rand(); /* discard first value to avoid undesirable correlations */
284 1 : return 0;
285 : }
286 :
287 :
288 684 : static int math_type (lua_State *L) {
289 684 : if (lua_type(L, 1) == LUA_TNUMBER) {
290 682 : if (lua_isinteger(L, 1))
291 480 : lua_pushliteral(L, "integer");
292 : else
293 202 : lua_pushliteral(L, "float");
294 : }
295 : else {
296 2 : luaL_checkany(L, 1);
297 2 : lua_pushnil(L);
298 : }
299 684 : return 1;
300 : }
301 :
302 :
303 : /*
304 : ** {==================================================================
305 : ** Deprecated functions (for compatibility only)
306 : ** ===================================================================
307 : */
308 : #if defined(LUA_COMPAT_MATHLIB)
309 :
310 : static int math_cosh (lua_State *L) {
311 : lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
312 : return 1;
313 : }
314 :
315 : static int math_sinh (lua_State *L) {
316 : lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
317 : return 1;
318 : }
319 :
320 : static int math_tanh (lua_State *L) {
321 : lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
322 : return 1;
323 : }
324 :
325 : static int math_pow (lua_State *L) {
326 : lua_Number x = luaL_checknumber(L, 1);
327 : lua_Number y = luaL_checknumber(L, 2);
328 : lua_pushnumber(L, l_mathop(pow)(x, y));
329 : return 1;
330 : }
331 :
332 : static int math_frexp (lua_State *L) {
333 : int e;
334 : lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
335 : lua_pushinteger(L, e);
336 : return 2;
337 : }
338 :
339 : static int math_ldexp (lua_State *L) {
340 : lua_Number x = luaL_checknumber(L, 1);
341 : int ep = (int)luaL_checkinteger(L, 2);
342 : lua_pushnumber(L, l_mathop(ldexp)(x, ep));
343 : return 1;
344 : }
345 :
346 : static int math_log10 (lua_State *L) {
347 : lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
348 : return 1;
349 : }
350 :
351 : #endif
352 : /* }================================================================== */
353 :
354 :
355 :
356 : static const luaL_Reg mathlib[] = {
357 : {"abs", math_abs},
358 : {"acos", math_acos},
359 : {"asin", math_asin},
360 : {"atan", math_atan},
361 : {"ceil", math_ceil},
362 : {"cos", math_cos},
363 : {"deg", math_deg},
364 : {"exp", math_exp},
365 : {"tointeger", math_toint},
366 : {"floor", math_floor},
367 : {"fmod", math_fmod},
368 : {"ult", math_ult},
369 : {"log", math_log},
370 : {"max", math_max},
371 : {"min", math_min},
372 : {"modf", math_modf},
373 : {"rad", math_rad},
374 : {"random", math_random},
375 : {"randomseed", math_randomseed},
376 : {"sin", math_sin},
377 : {"sqrt", math_sqrt},
378 : {"tan", math_tan},
379 : {"type", math_type},
380 : #if defined(LUA_COMPAT_MATHLIB)
381 : {"atan2", math_atan},
382 : {"cosh", math_cosh},
383 : {"sinh", math_sinh},
384 : {"tanh", math_tanh},
385 : {"pow", math_pow},
386 : {"frexp", math_frexp},
387 : {"ldexp", math_ldexp},
388 : {"log10", math_log10},
389 : #endif
390 : /* placeholders */
391 : {"pi", NULL},
392 : {"huge", NULL},
393 : {"maxinteger", NULL},
394 : {"mininteger", NULL},
395 : {NULL, NULL}
396 : };
397 :
398 :
399 : /*
400 : ** Open math library
401 : */
402 92 : LUAMOD_API int luaopen_math (lua_State *L) {
403 92 : luaL_newlib(L, mathlib);
404 92 : lua_pushnumber(L, PI);
405 92 : lua_setfield(L, -2, "pi");
406 92 : lua_pushnumber(L, (lua_Number)HUGE_VAL);
407 92 : lua_setfield(L, -2, "huge");
408 92 : lua_pushinteger(L, LUA_MAXINTEGER);
409 92 : lua_setfield(L, -2, "maxinteger");
410 92 : lua_pushinteger(L, LUA_MININTEGER);
411 92 : lua_setfield(L, -2, "mininteger");
412 92 : return 1;
413 : }
414 :
|