1 /*
2 ** $Id: lmathlib.cpp,v 1.1 2006/02/02 13:36:04 cavac 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
math_abs(lua_State * L)38 static int math_abs (lua_State *L) {
39 lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
40 return 1;
41 }
42
math_sin(lua_State * L)43 static int math_sin (lua_State *L) {
44 lua_pushnumber(L, sin(TORAD(luaL_checknumber(L, 1))));
45 return 1;
46 }
47
math_cos(lua_State * L)48 static int math_cos (lua_State *L) {
49 lua_pushnumber(L, cos(TORAD(luaL_checknumber(L, 1))));
50 return 1;
51 }
52
math_tan(lua_State * L)53 static int math_tan (lua_State *L) {
54 lua_pushnumber(L, tan(TORAD(luaL_checknumber(L, 1))));
55 return 1;
56 }
57
math_asin(lua_State * L)58 static int math_asin (lua_State *L) {
59 lua_pushnumber(L, FROMRAD(asin(luaL_checknumber(L, 1))));
60 return 1;
61 }
62
math_acos(lua_State * L)63 static int math_acos (lua_State *L) {
64 lua_pushnumber(L, FROMRAD(acos(luaL_checknumber(L, 1))));
65 return 1;
66 }
67
math_atan(lua_State * L)68 static int math_atan (lua_State *L) {
69 lua_pushnumber(L, FROMRAD(atan(luaL_checknumber(L, 1))));
70 return 1;
71 }
72
math_atan2(lua_State * L)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
math_ceil(lua_State * L)78 static int math_ceil (lua_State *L) {
79 lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
80 return 1;
81 }
82
math_floor(lua_State * L)83 static int math_floor (lua_State *L) {
84 lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
85 return 1;
86 }
87
math_mod(lua_State * L)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
math_sqrt(lua_State * L)93 static int math_sqrt (lua_State *L) {
94 lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
95 return 1;
96 }
97
math_pow(lua_State * L)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
math_log(lua_State * L)103 static int math_log (lua_State *L) {
104 lua_pushnumber(L, log(luaL_checknumber(L, 1)));
105 return 1;
106 }
107
math_log10(lua_State * L)108 static int math_log10 (lua_State *L) {
109 lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
110 return 1;
111 }
112
math_exp(lua_State * L)113 static int math_exp (lua_State *L) {
114 lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
115 return 1;
116 }
117
math_deg(lua_State * L)118 static int math_deg (lua_State *L) {
119 lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
120 return 1;
121 }
122
math_rad(lua_State * L)123 static int math_rad (lua_State *L) {
124 lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
125 return 1;
126 }
127
math_frexp(lua_State * L)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
math_ldexp(lua_State * L)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
math_min(lua_State * L)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
math_max(lua_State * L)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
math_random(lua_State * L)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
math_randomseed(lua_State * L)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 */
luaopen_math(lua_State * L)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
247