Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5205 clevermous 1
/*
2
** $Id: lmathlib.c,v 1.80 2011/07/05 12:49:35 roberto Exp $
3
** Standard mathematical library
4
** See Copyright Notice in lua.h
5
*/
6
 
7
 
8
#include 
9
#include 
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
/* macro 'l_tg' allows the addition of an 'l' or 'f' to all math operations */
26
#if !defined(l_tg)
27
#define l_tg(x)		(x)
28
#endif
29
 
30
 
31
 
32
static int math_abs (lua_State *L) {
33
  lua_pushnumber(L, l_tg(fabs)(luaL_checknumber(L, 1)));
34
  return 1;
35
}
36
 
37
static int math_sin (lua_State *L) {
38
  lua_pushnumber(L, l_tg(sin)(luaL_checknumber(L, 1)));
39
  return 1;
40
}
41
 
42
static int math_sinh (lua_State *L) {
43
  lua_pushnumber(L, l_tg(sinh)(luaL_checknumber(L, 1)));
44
  return 1;
45
}
46
 
47
static int math_cos (lua_State *L) {
48
  lua_pushnumber(L, l_tg(cos)(luaL_checknumber(L, 1)));
49
  return 1;
50
}
51
 
52
static int math_cosh (lua_State *L) {
53
  lua_pushnumber(L, l_tg(cosh)(luaL_checknumber(L, 1)));
54
  return 1;
55
}
56
 
57
static int math_tan (lua_State *L) {
58
  lua_pushnumber(L, l_tg(tan)(luaL_checknumber(L, 1)));
59
  return 1;
60
}
61
 
62
static int math_tanh (lua_State *L) {
63
  lua_pushnumber(L, l_tg(tanh)(luaL_checknumber(L, 1)));
64
  return 1;
65
}
66
 
67
static int math_asin (lua_State *L) {
68
  lua_pushnumber(L, l_tg(asin)(luaL_checknumber(L, 1)));
69
  return 1;
70
}
71
 
72
static int math_acos (lua_State *L) {
73
  lua_pushnumber(L, l_tg(acos)(luaL_checknumber(L, 1)));
74
  return 1;
75
}
76
 
77
static int math_atan (lua_State *L) {
78
  lua_pushnumber(L, l_tg(atan)(luaL_checknumber(L, 1)));
79
  return 1;
80
}
81
 
82
static 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
 
88
static int math_ceil (lua_State *L) {
89
  lua_pushnumber(L, l_tg(ceil)(luaL_checknumber(L, 1)));
90
  return 1;
91
}
92
 
93
static int math_floor (lua_State *L) {
94
  lua_pushnumber(L, l_tg(floor)(luaL_checknumber(L, 1)));
95
  return 1;
96
}
97
 
98
static 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
 
104
static 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
 
112
static int math_sqrt (lua_State *L) {
113
  lua_pushnumber(L, l_tg(sqrt)(luaL_checknumber(L, 1)));
114
  return 1;
115
}
116
 
117
static 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
 
123
static 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)
138
static int math_log10 (lua_State *L) {
139
  lua_pushnumber(L, l_tg(log10)(luaL_checknumber(L, 1)));
140
  return 1;
141
}
142
#endif
143
 
144
static int math_exp (lua_State *L) {
145
  lua_pushnumber(L, l_tg(exp)(luaL_checknumber(L, 1)));
146
  return 1;
147
}
148
 
149
static int math_deg (lua_State *L) {
150
  lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
151
  return 1;
152
}
153
 
154
static int math_rad (lua_State *L) {
155
  lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
156
  return 1;
157
}
158
 
159
static 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
 
166
static 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
 
174
static 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
 
188
static 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
 
202
static 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
 
230
static 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
 
237
static 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
*/
275
LUAMOD_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