1    	/*
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
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   	
22   	#undef PI
23   	#define PI	(l_mathop(3.141592653589793238462643383279502884))
24   	
25   	
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 */
31   	#else
32   	#define l_rand()	rand()
33   	#define l_srand(x)	srand(x)
34   	#define L_RANDMAX	RAND_MAX
35   	#endif
36   	#endif				/* } */
37   	
38   	
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);
44   	  }
45   	  else
46   	    lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
47   	  return 1;
48   	}
49   	
50   	static int math_sin (lua_State *L) {
51   	  lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
52   	  return 1;
53   	}
54   	
55   	static int math_cos (lua_State *L) {
56   	  lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
57   	  return 1;
58   	}
59   	
60   	static int math_tan (lua_State *L) {
61   	  lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
62   	  return 1;
63   	}
64   	
65   	static int math_asin (lua_State *L) {
66   	  lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
67   	  return 1;
68   	}
69   	
70   	static int math_acos (lua_State *L) {
71   	  lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
72   	  return 1;
73   	}
74   	
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));
79   	  return 1;
80   	}
81   	
82   	
83   	static int math_toint (lua_State *L) {
84   	  int valid;
85   	  lua_Integer n = lua_tointegerx(L, 1, &valid);
86   	  if (valid)
87   	    lua_pushinteger(L, n);
88   	  else {
89   	    luaL_checkany(L, 1);
90   	    lua_pushnil(L);  /* value is not convertible to integer */
91   	  }
92   	  return 1;
93   	}
94   	
95   	
96   	static void pushnumint (lua_State *L, lua_Number d) {
97   	  lua_Integer n;
98   	  if (lua_numbertointeger(d, &n))  /* does 'd' fit in an integer? */
99   	    lua_pushinteger(L, n);  /* result is integer */
100  	  else
101  	    lua_pushnumber(L, d);  /* result is float */
102  	}
103  	
104  	
105  	static int math_floor (lua_State *L) {
106  	  if (lua_isinteger(L, 1))
107  	    lua_settop(L, 1);  /* integer is its own floor */
108  	  else {
109  	    lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1));
110  	    pushnumint(L, d);
111  	  }
112  	  return 1;
113  	}
114  	
115  	
116  	static int math_ceil (lua_State *L) {
117  	  if (lua_isinteger(L, 1))
118  	    lua_settop(L, 1);  /* integer is its own ceil */
119  	  else {
120  	    lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1));
121  	    pushnumint(L, d);
122  	  }
123  	  return 1;
124  	}
125  	
126  	
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 */
133  	    }
134  	    else
135  	      lua_pushinteger(L, lua_tointeger(L, 1) % d);
136  	  }
137  	  else
138  	    lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
139  	                                     luaL_checknumber(L, 2)));
140  	  return 1;
141  	}
142  	
143  	
144  	/*
145  	** next function does not use 'modf', avoiding problems with 'double*'
146  	** (which is not compatible with 'float*') when lua_Number is not
147  	** 'double'.
148  	*/
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 */
153  	  }
154  	  else {
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);
158  	    pushnumint(L, ip);
159  	    /* fractional part (test needed for inf/-inf) */
160  	    lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip));
161  	  }
162  	  return 2;
163  	}
164  	
165  	
166  	static int math_sqrt (lua_State *L) {
167  	  lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
168  	  return 1;
169  	}
170  	
171  	
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);
176  	  return 1;
177  	}
178  	
179  	static int math_log (lua_State *L) {
180  	  lua_Number x = luaL_checknumber(L, 1);
181  	  lua_Number res;
182  	  if (lua_isnoneornil(L, 2))
183  	    res = l_mathop(log)(x);
184  	  else {
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
188  	#endif
189  	    if (base == 10.0) res = l_mathop(log10)(x);
190  	    else res = l_mathop(log)(x)/l_mathop(log)(base);
191  	  }
192  	  lua_pushnumber(L, res);
193  	  return 1;
194  	}
195  	
196  	static int math_exp (lua_State *L) {
197  	  lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
198  	  return 1;
199  	}
200  	
201  	static int math_deg (lua_State *L) {
202  	  lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI));
203  	  return 1;
204  	}
205  	
206  	static int math_rad (lua_State *L) {
207  	  lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0)));
208  	  return 1;
209  	}
210  	
211  	
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 */
215  	  int i;
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))
219  	      imin = i;
220  	  }
221  	  lua_pushvalue(L, imin);
222  	  return 1;
223  	}
224  	
225  	
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 */
229  	  int i;
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))
233  	      imax = i;
234  	  }
235  	  lua_pushvalue(L, imax);
236  	  return 1;
237  	}
238  	
239  	/*
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.)
243  	*/
244  	static int math_random (lua_State *L) {
245  	  lua_Integer low, up;
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 */
250  	      return 1;
251  	    }
252  	    case 1: {  /* only upper limit */
253  	      low = 1;
254  	      up = luaL_checkinteger(L, 1);
255  	      break;
256  	    }
257  	    case 2: {  /* lower and upper limits */
258  	      low = luaL_checkinteger(L, 1);
259  	      up = luaL_checkinteger(L, 2);
260  	      break;
261  	    }
262  	    default: return luaL_error(L, "wrong number of arguments");
263  	  }
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);
270  	  return 1;
271  	}
272  	
273  	
274  	static int math_randomseed (lua_State *L) {
275  	  l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1));
(1) Event dont_call: "random" should not be used for security-related applications, because linear congruential algorithms are too easy to break.
(2) Event remediation: Use a compliant random number generator, such as "/dev/random" or "/dev/urandom" on Unix-like systems, and CNG (Cryptography API: Next Generation) on Windows.
276  	  (void)l_rand(); /* discard first value to avoid undesirable correlations */
277  	  return 0;
278  	}
279  	
280  	
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"); 
285  	      else
286  	        lua_pushliteral(L, "float"); 
287  	  }
288  	  else {
289  	    luaL_checkany(L, 1);
290  	    lua_pushnil(L);
291  	  }
292  	  return 1;
293  	}
294  	
295  	
296  	/*
297  	** {==================================================================
298  	** Deprecated functions (for compatibility only)
299  	** ===================================================================
300  	*/
301  	#if defined(LUA_COMPAT_MATHLIB)
302  	
303  	static int math_cosh (lua_State *L) {
304  	  lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
305  	  return 1;
306  	}
307  	
308  	static int math_sinh (lua_State *L) {
309  	  lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
310  	  return 1;
311  	}
312  	
313  	static int math_tanh (lua_State *L) {
314  	  lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
315  	  return 1;
316  	}
317  	
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));
322  	  return 1;
323  	}
324  	
325  	static int math_frexp (lua_State *L) {
326  	  int e;
327  	  lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
328  	  lua_pushinteger(L, e);
329  	  return 2;
330  	}
331  	
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));
336  	  return 1;
337  	}
338  	
339  	static int math_log10 (lua_State *L) {
340  	  lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
341  	  return 1;
342  	}
343  	
344  	#endif
345  	/* }================================================================== */
346  	
347  	
348  	
349  	static const luaL_Reg mathlib[] = {
350  	  {"abs",   math_abs},
351  	  {"acos",  math_acos},
352  	  {"asin",  math_asin},
353  	  {"atan",  math_atan},
354  	  {"ceil",  math_ceil},
355  	  {"cos",   math_cos},
356  	  {"deg",   math_deg},
357  	  {"exp",   math_exp},
358  	  {"tointeger", math_toint},
359  	  {"floor", math_floor},
360  	  {"fmod",   math_fmod},
361  	  {"ult",   math_ult},
362  	  {"log",   math_log},
363  	  {"max",   math_max},
364  	  {"min",   math_min},
365  	  {"modf",   math_modf},
366  	  {"rad",   math_rad},
367  	  {"random",     math_random},
368  	  {"randomseed", math_randomseed},
369  	  {"sin",   math_sin},
370  	  {"sqrt",  math_sqrt},
371  	  {"tan",   math_tan},
372  	  {"type", math_type},
373  	#if defined(LUA_COMPAT_MATHLIB)
374  	  {"atan2", math_atan},
375  	  {"cosh",   math_cosh},
376  	  {"sinh",   math_sinh},
377  	  {"tanh",   math_tanh},
378  	  {"pow",   math_pow},
379  	  {"frexp", math_frexp},
380  	  {"ldexp", math_ldexp},
381  	  {"log10", math_log10},
382  	#endif
383  	  /* placeholders */
384  	  {"pi", NULL},
385  	  {"huge", NULL},
386  	  {"maxinteger", NULL},
387  	  {"mininteger", NULL},
388  	  {NULL, NULL}
389  	};
390  	
391  	
392  	/*
393  	** Open math library
394  	*/
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");
405  	  return 1;
406  	}
407  	
408