xref: /redis-3.2.3/deps/lua/src/lmathlib.c (revision 21d3294c)
1*21d3294cSantirez /*
2*21d3294cSantirez ** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $
3*21d3294cSantirez ** Standard mathematical library
4*21d3294cSantirez ** See Copyright Notice in lua.h
5*21d3294cSantirez */
6*21d3294cSantirez 
7*21d3294cSantirez 
8*21d3294cSantirez #include <stdlib.h>
9*21d3294cSantirez #include <math.h>
10*21d3294cSantirez 
11*21d3294cSantirez #define lmathlib_c
12*21d3294cSantirez #define LUA_LIB
13*21d3294cSantirez 
14*21d3294cSantirez #include "lua.h"
15*21d3294cSantirez 
16*21d3294cSantirez #include "lauxlib.h"
17*21d3294cSantirez #include "lualib.h"
18*21d3294cSantirez 
19*21d3294cSantirez 
20*21d3294cSantirez #undef PI
21*21d3294cSantirez #define PI (3.14159265358979323846)
22*21d3294cSantirez #define RADIANS_PER_DEGREE (PI/180.0)
23*21d3294cSantirez 
24*21d3294cSantirez 
25*21d3294cSantirez 
math_abs(lua_State * L)26*21d3294cSantirez static int math_abs (lua_State *L) {
27*21d3294cSantirez   lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
28*21d3294cSantirez   return 1;
29*21d3294cSantirez }
30*21d3294cSantirez 
math_sin(lua_State * L)31*21d3294cSantirez static int math_sin (lua_State *L) {
32*21d3294cSantirez   lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
33*21d3294cSantirez   return 1;
34*21d3294cSantirez }
35*21d3294cSantirez 
math_sinh(lua_State * L)36*21d3294cSantirez static int math_sinh (lua_State *L) {
37*21d3294cSantirez   lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
38*21d3294cSantirez   return 1;
39*21d3294cSantirez }
40*21d3294cSantirez 
math_cos(lua_State * L)41*21d3294cSantirez static int math_cos (lua_State *L) {
42*21d3294cSantirez   lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
43*21d3294cSantirez   return 1;
44*21d3294cSantirez }
45*21d3294cSantirez 
math_cosh(lua_State * L)46*21d3294cSantirez static int math_cosh (lua_State *L) {
47*21d3294cSantirez   lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
48*21d3294cSantirez   return 1;
49*21d3294cSantirez }
50*21d3294cSantirez 
math_tan(lua_State * L)51*21d3294cSantirez static int math_tan (lua_State *L) {
52*21d3294cSantirez   lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
53*21d3294cSantirez   return 1;
54*21d3294cSantirez }
55*21d3294cSantirez 
math_tanh(lua_State * L)56*21d3294cSantirez static int math_tanh (lua_State *L) {
57*21d3294cSantirez   lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
58*21d3294cSantirez   return 1;
59*21d3294cSantirez }
60*21d3294cSantirez 
math_asin(lua_State * L)61*21d3294cSantirez static int math_asin (lua_State *L) {
62*21d3294cSantirez   lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
63*21d3294cSantirez   return 1;
64*21d3294cSantirez }
65*21d3294cSantirez 
math_acos(lua_State * L)66*21d3294cSantirez static int math_acos (lua_State *L) {
67*21d3294cSantirez   lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
68*21d3294cSantirez   return 1;
69*21d3294cSantirez }
70*21d3294cSantirez 
math_atan(lua_State * L)71*21d3294cSantirez static int math_atan (lua_State *L) {
72*21d3294cSantirez   lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
73*21d3294cSantirez   return 1;
74*21d3294cSantirez }
75*21d3294cSantirez 
math_atan2(lua_State * L)76*21d3294cSantirez static int math_atan2 (lua_State *L) {
77*21d3294cSantirez   lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
78*21d3294cSantirez   return 1;
79*21d3294cSantirez }
80*21d3294cSantirez 
math_ceil(lua_State * L)81*21d3294cSantirez static int math_ceil (lua_State *L) {
82*21d3294cSantirez   lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
83*21d3294cSantirez   return 1;
84*21d3294cSantirez }
85*21d3294cSantirez 
math_floor(lua_State * L)86*21d3294cSantirez static int math_floor (lua_State *L) {
87*21d3294cSantirez   lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
88*21d3294cSantirez   return 1;
89*21d3294cSantirez }
90*21d3294cSantirez 
math_fmod(lua_State * L)91*21d3294cSantirez static int math_fmod (lua_State *L) {
92*21d3294cSantirez   lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
93*21d3294cSantirez   return 1;
94*21d3294cSantirez }
95*21d3294cSantirez 
math_modf(lua_State * L)96*21d3294cSantirez static int math_modf (lua_State *L) {
97*21d3294cSantirez   double ip;
98*21d3294cSantirez   double fp = modf(luaL_checknumber(L, 1), &ip);
99*21d3294cSantirez   lua_pushnumber(L, ip);
100*21d3294cSantirez   lua_pushnumber(L, fp);
101*21d3294cSantirez   return 2;
102*21d3294cSantirez }
103*21d3294cSantirez 
math_sqrt(lua_State * L)104*21d3294cSantirez static int math_sqrt (lua_State *L) {
105*21d3294cSantirez   lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
106*21d3294cSantirez   return 1;
107*21d3294cSantirez }
108*21d3294cSantirez 
math_pow(lua_State * L)109*21d3294cSantirez static int math_pow (lua_State *L) {
110*21d3294cSantirez   lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
111*21d3294cSantirez   return 1;
112*21d3294cSantirez }
113*21d3294cSantirez 
math_log(lua_State * L)114*21d3294cSantirez static int math_log (lua_State *L) {
115*21d3294cSantirez   lua_pushnumber(L, log(luaL_checknumber(L, 1)));
116*21d3294cSantirez   return 1;
117*21d3294cSantirez }
118*21d3294cSantirez 
math_log10(lua_State * L)119*21d3294cSantirez static int math_log10 (lua_State *L) {
120*21d3294cSantirez   lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
121*21d3294cSantirez   return 1;
122*21d3294cSantirez }
123*21d3294cSantirez 
math_exp(lua_State * L)124*21d3294cSantirez static int math_exp (lua_State *L) {
125*21d3294cSantirez   lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
126*21d3294cSantirez   return 1;
127*21d3294cSantirez }
128*21d3294cSantirez 
math_deg(lua_State * L)129*21d3294cSantirez static int math_deg (lua_State *L) {
130*21d3294cSantirez   lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
131*21d3294cSantirez   return 1;
132*21d3294cSantirez }
133*21d3294cSantirez 
math_rad(lua_State * L)134*21d3294cSantirez static int math_rad (lua_State *L) {
135*21d3294cSantirez   lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
136*21d3294cSantirez   return 1;
137*21d3294cSantirez }
138*21d3294cSantirez 
math_frexp(lua_State * L)139*21d3294cSantirez static int math_frexp (lua_State *L) {
140*21d3294cSantirez   int e;
141*21d3294cSantirez   lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
142*21d3294cSantirez   lua_pushinteger(L, e);
143*21d3294cSantirez   return 2;
144*21d3294cSantirez }
145*21d3294cSantirez 
math_ldexp(lua_State * L)146*21d3294cSantirez static int math_ldexp (lua_State *L) {
147*21d3294cSantirez   lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
148*21d3294cSantirez   return 1;
149*21d3294cSantirez }
150*21d3294cSantirez 
151*21d3294cSantirez 
152*21d3294cSantirez 
math_min(lua_State * L)153*21d3294cSantirez static int math_min (lua_State *L) {
154*21d3294cSantirez   int n = lua_gettop(L);  /* number of arguments */
155*21d3294cSantirez   lua_Number dmin = luaL_checknumber(L, 1);
156*21d3294cSantirez   int i;
157*21d3294cSantirez   for (i=2; i<=n; i++) {
158*21d3294cSantirez     lua_Number d = luaL_checknumber(L, i);
159*21d3294cSantirez     if (d < dmin)
160*21d3294cSantirez       dmin = d;
161*21d3294cSantirez   }
162*21d3294cSantirez   lua_pushnumber(L, dmin);
163*21d3294cSantirez   return 1;
164*21d3294cSantirez }
165*21d3294cSantirez 
166*21d3294cSantirez 
math_max(lua_State * L)167*21d3294cSantirez static int math_max (lua_State *L) {
168*21d3294cSantirez   int n = lua_gettop(L);  /* number of arguments */
169*21d3294cSantirez   lua_Number dmax = luaL_checknumber(L, 1);
170*21d3294cSantirez   int i;
171*21d3294cSantirez   for (i=2; i<=n; i++) {
172*21d3294cSantirez     lua_Number d = luaL_checknumber(L, i);
173*21d3294cSantirez     if (d > dmax)
174*21d3294cSantirez       dmax = d;
175*21d3294cSantirez   }
176*21d3294cSantirez   lua_pushnumber(L, dmax);
177*21d3294cSantirez   return 1;
178*21d3294cSantirez }
179*21d3294cSantirez 
180*21d3294cSantirez 
math_random(lua_State * L)181*21d3294cSantirez static int math_random (lua_State *L) {
182*21d3294cSantirez   /* the `%' avoids the (rare) case of r==1, and is needed also because on
183*21d3294cSantirez      some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
184*21d3294cSantirez   lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
185*21d3294cSantirez   switch (lua_gettop(L)) {  /* check number of arguments */
186*21d3294cSantirez     case 0: {  /* no arguments */
187*21d3294cSantirez       lua_pushnumber(L, r);  /* Number between 0 and 1 */
188*21d3294cSantirez       break;
189*21d3294cSantirez     }
190*21d3294cSantirez     case 1: {  /* only upper limit */
191*21d3294cSantirez       int u = luaL_checkint(L, 1);
192*21d3294cSantirez       luaL_argcheck(L, 1<=u, 1, "interval is empty");
193*21d3294cSantirez       lua_pushnumber(L, floor(r*u)+1);  /* int between 1 and `u' */
194*21d3294cSantirez       break;
195*21d3294cSantirez     }
196*21d3294cSantirez     case 2: {  /* lower and upper limits */
197*21d3294cSantirez       int l = luaL_checkint(L, 1);
198*21d3294cSantirez       int u = luaL_checkint(L, 2);
199*21d3294cSantirez       luaL_argcheck(L, l<=u, 2, "interval is empty");
200*21d3294cSantirez       lua_pushnumber(L, floor(r*(u-l+1))+l);  /* int between `l' and `u' */
201*21d3294cSantirez       break;
202*21d3294cSantirez     }
203*21d3294cSantirez     default: return luaL_error(L, "wrong number of arguments");
204*21d3294cSantirez   }
205*21d3294cSantirez   return 1;
206*21d3294cSantirez }
207*21d3294cSantirez 
208*21d3294cSantirez 
math_randomseed(lua_State * L)209*21d3294cSantirez static int math_randomseed (lua_State *L) {
210*21d3294cSantirez   srand(luaL_checkint(L, 1));
211*21d3294cSantirez   return 0;
212*21d3294cSantirez }
213*21d3294cSantirez 
214*21d3294cSantirez 
215*21d3294cSantirez static const luaL_Reg mathlib[] = {
216*21d3294cSantirez   {"abs",   math_abs},
217*21d3294cSantirez   {"acos",  math_acos},
218*21d3294cSantirez   {"asin",  math_asin},
219*21d3294cSantirez   {"atan2", math_atan2},
220*21d3294cSantirez   {"atan",  math_atan},
221*21d3294cSantirez   {"ceil",  math_ceil},
222*21d3294cSantirez   {"cosh",   math_cosh},
223*21d3294cSantirez   {"cos",   math_cos},
224*21d3294cSantirez   {"deg",   math_deg},
225*21d3294cSantirez   {"exp",   math_exp},
226*21d3294cSantirez   {"floor", math_floor},
227*21d3294cSantirez   {"fmod",   math_fmod},
228*21d3294cSantirez   {"frexp", math_frexp},
229*21d3294cSantirez   {"ldexp", math_ldexp},
230*21d3294cSantirez   {"log10", math_log10},
231*21d3294cSantirez   {"log",   math_log},
232*21d3294cSantirez   {"max",   math_max},
233*21d3294cSantirez   {"min",   math_min},
234*21d3294cSantirez   {"modf",   math_modf},
235*21d3294cSantirez   {"pow",   math_pow},
236*21d3294cSantirez   {"rad",   math_rad},
237*21d3294cSantirez   {"random",     math_random},
238*21d3294cSantirez   {"randomseed", math_randomseed},
239*21d3294cSantirez   {"sinh",   math_sinh},
240*21d3294cSantirez   {"sin",   math_sin},
241*21d3294cSantirez   {"sqrt",  math_sqrt},
242*21d3294cSantirez   {"tanh",   math_tanh},
243*21d3294cSantirez   {"tan",   math_tan},
244*21d3294cSantirez   {NULL, NULL}
245*21d3294cSantirez };
246*21d3294cSantirez 
247*21d3294cSantirez 
248*21d3294cSantirez /*
249*21d3294cSantirez ** Open math library
250*21d3294cSantirez */
luaopen_math(lua_State * L)251*21d3294cSantirez LUALIB_API int luaopen_math (lua_State *L) {
252*21d3294cSantirez   luaL_register(L, LUA_MATHLIBNAME, mathlib);
253*21d3294cSantirez   lua_pushnumber(L, PI);
254*21d3294cSantirez   lua_setfield(L, -2, "pi");
255*21d3294cSantirez   lua_pushnumber(L, HUGE_VAL);
256*21d3294cSantirez   lua_setfield(L, -2, "huge");
257*21d3294cSantirez #if defined(LUA_COMPAT_MOD)
258*21d3294cSantirez   lua_getfield(L, -1, "fmod");
259*21d3294cSantirez   lua_setfield(L, -2, "mod");
260*21d3294cSantirez #endif
261*21d3294cSantirez   return 1;
262*21d3294cSantirez }
263*21d3294cSantirez 
264