source: trunk/src/lua/lmathlib.c @ 2540

Last change on this file since 2540 was 2540, checked in by sam, 10 years ago

core: import pristine lua 5.2.1 in the engine code.

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