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