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