Imported from ../lua-4.0.1.tar.gz.
[lua.git] / src / lib / lmathlib.c
blobc062cf49756f3bde160d5baa72bc33ed6ea5f140
1 /*
2 ** $Id: lmathlib.c,v 1.32 2000/10/31 13:10:24 roberto Exp $
3 ** Standard mathematical library
4 ** See Copyright Notice in lua.h
5 */
8 #include <stdlib.h>
9 #include <math.h>
11 #include "lua.h"
13 #include "lauxlib.h"
14 #include "lualib.h"
17 #undef PI
18 #define PI (3.14159265358979323846)
19 #define RADIANS_PER_DEGREE (PI/180.0)
24 ** If you want Lua to operate in radians (instead of degrees),
25 ** define RADIANS
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
36 static int math_abs (lua_State *L) {
37 lua_pushnumber(L, fabs(luaL_check_number(L, 1)));
38 return 1;
41 static int math_sin (lua_State *L) {
42 lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1))));
43 return 1;
46 static int math_cos (lua_State *L) {
47 lua_pushnumber(L, cos(TORAD(luaL_check_number(L, 1))));
48 return 1;
51 static int math_tan (lua_State *L) {
52 lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1))));
53 return 1;
56 static int math_asin (lua_State *L) {
57 lua_pushnumber(L, FROMRAD(asin(luaL_check_number(L, 1))));
58 return 1;
61 static int math_acos (lua_State *L) {
62 lua_pushnumber(L, FROMRAD(acos(luaL_check_number(L, 1))));
63 return 1;
66 static int math_atan (lua_State *L) {
67 lua_pushnumber(L, FROMRAD(atan(luaL_check_number(L, 1))));
68 return 1;
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;
76 static int math_ceil (lua_State *L) {
77 lua_pushnumber(L, ceil(luaL_check_number(L, 1)));
78 return 1;
81 static int math_floor (lua_State *L) {
82 lua_pushnumber(L, floor(luaL_check_number(L, 1)));
83 return 1;
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;
91 static int math_sqrt (lua_State *L) {
92 lua_pushnumber(L, sqrt(luaL_check_number(L, 1)));
93 return 1;
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;
101 static int math_log (lua_State *L) {
102 lua_pushnumber(L, log(luaL_check_number(L, 1)));
103 return 1;
106 static int math_log10 (lua_State *L) {
107 lua_pushnumber(L, log10(luaL_check_number(L, 1)));
108 return 1;
111 static int math_exp (lua_State *L) {
112 lua_pushnumber(L, exp(luaL_check_number(L, 1)));
113 return 1;
116 static int math_deg (lua_State *L) {
117 lua_pushnumber(L, luaL_check_number(L, 1)/RADIANS_PER_DEGREE);
118 return 1;
121 static int math_rad (lua_State *L) {
122 lua_pushnumber(L, luaL_check_number(L, 1)*RADIANS_PER_DEGREE);
123 return 1;
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;
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;
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;
149 lua_pushnumber(L, dmin);
150 return 1;
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;
163 lua_pushnumber(L, dmax);
164 return 1;
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;
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;
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;
190 default: lua_error(L, "wrong number of arguments");
192 return 1;
196 static int math_randomseed (lua_State *L) {
197 srand(luaL_check_int(L, 1));
198 return 0;
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}
229 ** Open math library
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");