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