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