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