Branch data Line data Source code
1 : : /*
2 : : ** $Id: lmathlib.c $
3 : : ** Standard mathematical library
4 : : ** See Copyright Notice in lua.h
5 : : */
6 : :
7 : : #define lmathlib_c
8 : : #define LUA_LIB
9 : :
10 : : #include "lprefix.h"
11 : :
12 : :
13 : : #include <float.h>
14 : : #include <limits.h>
15 : : #include <math.h>
16 : : #include <stdlib.h>
17 : : #include <time.h>
18 : :
19 : : #include "lua.h"
20 : :
21 : : #include "lauxlib.h"
22 : : #include "lualib.h"
23 : :
24 : :
25 : : #undef PI
26 : : #define PI (l_mathop(3.141592653589793238462643383279502884))
27 : :
28 : :
29 : 0 : static int math_abs (lua_State *L) {
30 [ # # ]: 0 : if (lua_isinteger(L, 1)) {
31 : 0 : lua_Integer n = lua_tointeger(L, 1);
32 [ # # ]: 0 : if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n);
33 : 0 : lua_pushinteger(L, n);
34 : 0 : }
35 : : else
36 : 0 : lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
37 : 0 : return 1;
38 : : }
39 : :
40 : 0 : static int math_sin (lua_State *L) {
41 : 0 : lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
42 : 0 : return 1;
43 : : }
44 : :
45 : 0 : static int math_cos (lua_State *L) {
46 : 0 : lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
47 : 0 : return 1;
48 : : }
49 : :
50 : 0 : static int math_tan (lua_State *L) {
51 : 0 : lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
52 : 0 : return 1;
53 : : }
54 : :
55 : 0 : static int math_asin (lua_State *L) {
56 : 0 : lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
57 : 0 : return 1;
58 : : }
59 : :
60 : 0 : static int math_acos (lua_State *L) {
61 : 0 : lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
62 : 0 : return 1;
63 : : }
64 : :
65 : 0 : static int math_atan (lua_State *L) {
66 : 0 : lua_Number y = luaL_checknumber(L, 1);
67 : 0 : lua_Number x = luaL_optnumber(L, 2, 1);
68 : 0 : lua_pushnumber(L, l_mathop(atan2)(y, x));
69 : 0 : return 1;
70 : : }
71 : :
72 : :
73 : 0 : static int math_toint (lua_State *L) {
74 : : int valid;
75 : 0 : lua_Integer n = lua_tointegerx(L, 1, &valid);
76 [ # # ]: 0 : if (valid)
77 : 0 : lua_pushinteger(L, n);
78 : : else {
79 : 0 : luaL_checkany(L, 1);
80 : 0 : luaL_pushfail(L); /* value is not convertible to integer */
81 : : }
82 : 0 : return 1;
83 : : }
84 : :
85 : :
86 : 0 : static void pushnumint (lua_State *L, lua_Number d) {
87 : : lua_Integer n;
88 [ # # # # : 0 : if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */
# # ]
89 : 0 : lua_pushinteger(L, n); /* result is integer */
90 : : else
91 : 0 : lua_pushnumber(L, d); /* result is float */
92 : 0 : }
93 : :
94 : :
95 : 0 : static int math_floor (lua_State *L) {
96 [ # # ]: 0 : if (lua_isinteger(L, 1))
97 : 0 : lua_settop(L, 1); /* integer is its own floor */
98 : : else {
99 : 0 : lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1));
100 : 0 : pushnumint(L, d);
101 : : }
102 : 0 : return 1;
103 : : }
104 : :
105 : :
106 : 0 : static int math_ceil (lua_State *L) {
107 [ # # ]: 0 : if (lua_isinteger(L, 1))
108 : 0 : lua_settop(L, 1); /* integer is its own ceil */
109 : : else {
110 : 0 : lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1));
111 : 0 : pushnumint(L, d);
112 : : }
113 : 0 : return 1;
114 : : }
115 : :
116 : :
117 : 0 : static int math_fmod (lua_State *L) {
118 [ # # # # ]: 0 : if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) {
119 : 0 : lua_Integer d = lua_tointeger(L, 2);
120 [ # # ]: 0 : if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */
121 [ # # ]: 0 : luaL_argcheck(L, d != 0, 2, "zero");
122 : 0 : lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */
123 : 0 : }
124 : : else
125 : 0 : lua_pushinteger(L, lua_tointeger(L, 1) % d);
126 : 0 : }
127 : : else
128 : 0 : lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
129 : 0 : luaL_checknumber(L, 2)));
130 : 0 : return 1;
131 : : }
132 : :
133 : :
134 : : /*
135 : : ** next function does not use 'modf', avoiding problems with 'double*'
136 : : ** (which is not compatible with 'float*') when lua_Number is not
137 : : ** 'double'.
138 : : */
139 : 0 : static int math_modf (lua_State *L) {
140 [ # # ]: 0 : if (lua_isinteger(L ,1)) {
141 : 0 : lua_settop(L, 1); /* number is its own integer part */
142 : 0 : lua_pushnumber(L, 0); /* no fractional part */
143 : 0 : }
144 : : else {
145 : 0 : lua_Number n = luaL_checknumber(L, 1);
146 : : /* integer part (rounds toward zero) */
147 [ # # ]: 0 : lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n);
148 : 0 : pushnumint(L, ip);
149 : : /* fractional part (test needed for inf/-inf) */
150 [ # # ]: 0 : lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip));
151 : : }
152 : 0 : return 2;
153 : : }
154 : :
155 : :
156 : 0 : static int math_sqrt (lua_State *L) {
157 : 0 : lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
158 : 0 : return 1;
159 : : }
160 : :
161 : :
162 : 0 : static int math_ult (lua_State *L) {
163 : 0 : lua_Integer a = luaL_checkinteger(L, 1);
164 : 0 : lua_Integer b = luaL_checkinteger(L, 2);
165 : 0 : lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b);
166 : 0 : return 1;
167 : : }
168 : :
169 : 0 : static int math_log (lua_State *L) {
170 : 0 : lua_Number x = luaL_checknumber(L, 1);
171 : : lua_Number res;
172 [ # # ]: 0 : if (lua_isnoneornil(L, 2))
173 : 0 : res = l_mathop(log)(x);
174 : : else {
175 : 0 : lua_Number base = luaL_checknumber(L, 2);
176 : : #if !defined(LUA_USE_C89)
177 [ # # ]: 0 : if (base == l_mathop(2.0))
178 : 0 : res = l_mathop(log2)(x); else
179 : : #endif
180 [ # # ]: 0 : if (base == l_mathop(10.0))
181 : 0 : res = l_mathop(log10)(x);
182 : : else
183 : 0 : res = l_mathop(log)(x)/l_mathop(log)(base);
184 : : }
185 : 0 : lua_pushnumber(L, res);
186 : 0 : return 1;
187 : : }
188 : :
189 : 0 : static int math_exp (lua_State *L) {
190 : 0 : lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
191 : 0 : return 1;
192 : : }
193 : :
194 : 0 : static int math_deg (lua_State *L) {
195 : 0 : lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI));
196 : 0 : return 1;
197 : : }
198 : :
199 : 0 : static int math_rad (lua_State *L) {
200 : 0 : lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0)));
201 : 0 : return 1;
202 : : }
203 : :
204 : :
205 : 0 : static int math_min (lua_State *L) {
206 : 0 : int n = lua_gettop(L); /* number of arguments */
207 : 0 : int imin = 1; /* index of current minimum value */
208 : : int i;
209 [ # # ]: 0 : luaL_argcheck(L, n >= 1, 1, "value expected");
210 [ # # ]: 0 : for (i = 2; i <= n; i++) {
211 [ # # ]: 0 : if (lua_compare(L, i, imin, LUA_OPLT))
212 : 0 : imin = i;
213 : 0 : }
214 : 0 : lua_pushvalue(L, imin);
215 : 0 : return 1;
216 : : }
217 : :
218 : :
219 : 0 : static int math_max (lua_State *L) {
220 : 0 : int n = lua_gettop(L); /* number of arguments */
221 : 0 : int imax = 1; /* index of current maximum value */
222 : : int i;
223 [ # # ]: 0 : luaL_argcheck(L, n >= 1, 1, "value expected");
224 [ # # ]: 0 : for (i = 2; i <= n; i++) {
225 [ # # ]: 0 : if (lua_compare(L, imax, i, LUA_OPLT))
226 : 0 : imax = i;
227 : 0 : }
228 : 0 : lua_pushvalue(L, imax);
229 : 0 : return 1;
230 : : }
231 : :
232 : :
233 : 0 : static int math_type (lua_State *L) {
234 [ # # ]: 0 : if (lua_type(L, 1) == LUA_TNUMBER)
235 : 0 : lua_pushstring(L, (lua_isinteger(L, 1)) ? "integer" : "float");
236 : : else {
237 : 0 : luaL_checkany(L, 1);
238 : 0 : luaL_pushfail(L);
239 : : }
240 : 0 : return 1;
241 : : }
242 : :
243 : :
244 : :
245 : : /*
246 : : ** {==================================================================
247 : : ** Pseudo-Random Number Generator based on 'xoshiro256**'.
248 : : ** ===================================================================
249 : : */
250 : :
251 : : /* number of binary digits in the mantissa of a float */
252 : : #define FIGS l_floatatt(MANT_DIG)
253 : :
254 : : #if FIGS > 64
255 : : /* there are only 64 random bits; use them all */
256 : : #undef FIGS
257 : : #define FIGS 64
258 : : #endif
259 : :
260 : :
261 : : /*
262 : : ** LUA_RAND32 forces the use of 32-bit integers in the implementation
263 : : ** of the PRN generator (mainly for testing).
264 : : */
265 : : #if !defined(LUA_RAND32) && !defined(Rand64)
266 : :
267 : : /* try to find an integer type with at least 64 bits */
268 : :
269 : : #if (ULONG_MAX >> 31 >> 31) >= 3
270 : :
271 : : /* 'long' has at least 64 bits */
272 : : #define Rand64 unsigned long
273 : :
274 : : #elif !defined(LUA_USE_C89) && defined(LLONG_MAX)
275 : :
276 : : /* there is a 'long long' type (which must have at least 64 bits) */
277 : : #define Rand64 unsigned long long
278 : :
279 : : #elif (LUA_MAXUNSIGNED >> 31 >> 31) >= 3
280 : :
281 : : /* 'lua_Integer' has at least 64 bits */
282 : : #define Rand64 lua_Unsigned
283 : :
284 : : #endif
285 : :
286 : : #endif
287 : :
288 : :
289 : : #if defined(Rand64) /* { */
290 : :
291 : : /*
292 : : ** Standard implementation, using 64-bit integers.
293 : : ** If 'Rand64' has more than 64 bits, the extra bits do not interfere
294 : : ** with the 64 initial bits, except in a right shift. Moreover, the
295 : : ** final result has to discard the extra bits.
296 : : */
297 : :
298 : : /* avoid using extra bits when needed */
299 : : #define trim64(x) ((x) & 0xffffffffffffffffu)
300 : :
301 : :
302 : : /* rotate left 'x' by 'n' bits */
303 : 25920 : static Rand64 rotl (Rand64 x, int n) {
304 : 25920 : return (x << n) | (trim64(x) >> (64 - n));
305 : : }
306 : :
307 : 12960 : static Rand64 nextrand (Rand64 *state) {
308 : 12960 : Rand64 state0 = state[0];
309 : 12960 : Rand64 state1 = state[1];
310 : 12960 : Rand64 state2 = state[2] ^ state0;
311 : 12960 : Rand64 state3 = state[3] ^ state1;
312 : 12960 : Rand64 res = rotl(state1 * 5, 7) * 9;
313 : 12960 : state[0] = state0 ^ state3;
314 : 12960 : state[1] = state1 ^ state2;
315 : 12960 : state[2] = state2 ^ (state1 << 17);
316 : 12960 : state[3] = rotl(state3, 45);
317 : 12960 : return res;
318 : : }
319 : :
320 : :
321 : : /* must take care to not shift stuff by more than 63 slots */
322 : :
323 : :
324 : : /*
325 : : ** Convert bits from a random integer into a float in the
326 : : ** interval [0,1), getting the higher FIG bits from the
327 : : ** random unsigned integer and converting that to a float.
328 : : */
329 : :
330 : : /* must throw out the extra (64 - FIGS) bits */
331 : : #define shift64_FIG (64 - FIGS)
332 : :
333 : : /* to scale to [0, 1), multiply by scaleFIG = 2^(-FIGS) */
334 : : #define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1)))
335 : :
336 : 0 : static lua_Number I2d (Rand64 x) {
337 : 0 : return (lua_Number)(trim64(x) >> shift64_FIG) * scaleFIG;
338 : : }
339 : :
340 : : /* convert a 'Rand64' to a 'lua_Unsigned' */
341 : : #define I2UInt(x) ((lua_Unsigned)trim64(x))
342 : :
343 : : /* convert a 'lua_Unsigned' to a 'Rand64' */
344 : : #define Int2I(x) ((Rand64)(x))
345 : :
346 : :
347 : : #else /* no 'Rand64' }{ */
348 : :
349 : : /* get an integer with at least 32 bits */
350 : : #if LUAI_IS32INT
351 : : typedef unsigned int lu_int32;
352 : : #else
353 : : typedef unsigned long lu_int32;
354 : : #endif
355 : :
356 : :
357 : : /*
358 : : ** Use two 32-bit integers to represent a 64-bit quantity.
359 : : */
360 : : typedef struct Rand64 {
361 : : lu_int32 h; /* higher half */
362 : : lu_int32 l; /* lower half */
363 : : } Rand64;
364 : :
365 : :
366 : : /*
367 : : ** If 'lu_int32' has more than 32 bits, the extra bits do not interfere
368 : : ** with the 32 initial bits, except in a right shift and comparisons.
369 : : ** Moreover, the final result has to discard the extra bits.
370 : : */
371 : :
372 : : /* avoid using extra bits when needed */
373 : : #define trim32(x) ((x) & 0xffffffffu)
374 : :
375 : :
376 : : /*
377 : : ** basic operations on 'Rand64' values
378 : : */
379 : :
380 : : /* build a new Rand64 value */
381 : : static Rand64 packI (lu_int32 h, lu_int32 l) {
382 : : Rand64 result;
383 : : result.h = h;
384 : : result.l = l;
385 : : return result;
386 : : }
387 : :
388 : : /* return i << n */
389 : : static Rand64 Ishl (Rand64 i, int n) {
390 : : lua_assert(n > 0 && n < 32);
391 : : return packI((i.h << n) | (trim32(i.l) >> (32 - n)), i.l << n);
392 : : }
393 : :
394 : : /* i1 ^= i2 */
395 : : static void Ixor (Rand64 *i1, Rand64 i2) {
396 : : i1->h ^= i2.h;
397 : : i1->l ^= i2.l;
398 : : }
399 : :
400 : : /* return i1 + i2 */
401 : : static Rand64 Iadd (Rand64 i1, Rand64 i2) {
402 : : Rand64 result = packI(i1.h + i2.h, i1.l + i2.l);
403 : : if (trim32(result.l) < trim32(i1.l)) /* carry? */
404 : : result.h++;
405 : : return result;
406 : : }
407 : :
408 : : /* return i * 5 */
409 : : static Rand64 times5 (Rand64 i) {
410 : : return Iadd(Ishl(i, 2), i); /* i * 5 == (i << 2) + i */
411 : : }
412 : :
413 : : /* return i * 9 */
414 : : static Rand64 times9 (Rand64 i) {
415 : : return Iadd(Ishl(i, 3), i); /* i * 9 == (i << 3) + i */
416 : : }
417 : :
418 : : /* return 'i' rotated left 'n' bits */
419 : : static Rand64 rotl (Rand64 i, int n) {
420 : : lua_assert(n > 0 && n < 32);
421 : : return packI((i.h << n) | (trim32(i.l) >> (32 - n)),
422 : : (trim32(i.h) >> (32 - n)) | (i.l << n));
423 : : }
424 : :
425 : : /* for offsets larger than 32, rotate right by 64 - offset */
426 : : static Rand64 rotl1 (Rand64 i, int n) {
427 : : lua_assert(n > 32 && n < 64);
428 : : n = 64 - n;
429 : : return packI((trim32(i.h) >> n) | (i.l << (32 - n)),
430 : : (i.h << (32 - n)) | (trim32(i.l) >> n));
431 : : }
432 : :
433 : : /*
434 : : ** implementation of 'xoshiro256**' algorithm on 'Rand64' values
435 : : */
436 : : static Rand64 nextrand (Rand64 *state) {
437 : : Rand64 res = times9(rotl(times5(state[1]), 7));
438 : : Rand64 t = Ishl(state[1], 17);
439 : : Ixor(&state[2], state[0]);
440 : : Ixor(&state[3], state[1]);
441 : : Ixor(&state[1], state[2]);
442 : : Ixor(&state[0], state[3]);
443 : : Ixor(&state[2], t);
444 : : state[3] = rotl1(state[3], 45);
445 : : return res;
446 : : }
447 : :
448 : :
449 : : /*
450 : : ** Converts a 'Rand64' into a float.
451 : : */
452 : :
453 : : /* an unsigned 1 with proper type */
454 : : #define UONE ((lu_int32)1)
455 : :
456 : :
457 : : #if FIGS <= 32
458 : :
459 : : /* 2^(-FIGS) */
460 : : #define scaleFIG (l_mathop(0.5) / (UONE << (FIGS - 1)))
461 : :
462 : : /*
463 : : ** get up to 32 bits from higher half, shifting right to
464 : : ** throw out the extra bits.
465 : : */
466 : : static lua_Number I2d (Rand64 x) {
467 : : lua_Number h = (lua_Number)(trim32(x.h) >> (32 - FIGS));
468 : : return h * scaleFIG;
469 : : }
470 : :
471 : : #else /* 32 < FIGS <= 64 */
472 : :
473 : : /* must take care to not shift stuff by more than 31 slots */
474 : :
475 : : /* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */
476 : : #define scaleFIG \
477 : : ((lua_Number)1.0 / (UONE << 30) / 8.0 / (UONE << (FIGS - 33)))
478 : :
479 : : /*
480 : : ** use FIGS - 32 bits from lower half, throwing out the other
481 : : ** (32 - (FIGS - 32)) = (64 - FIGS) bits
482 : : */
483 : : #define shiftLOW (64 - FIGS)
484 : :
485 : : /*
486 : : ** higher 32 bits go after those (FIGS - 32) bits: shiftHI = 2^(FIGS - 32)
487 : : */
488 : : #define shiftHI ((lua_Number)(UONE << (FIGS - 33)) * 2.0)
489 : :
490 : :
491 : : static lua_Number I2d (Rand64 x) {
492 : : lua_Number h = (lua_Number)trim32(x.h) * shiftHI;
493 : : lua_Number l = (lua_Number)(trim32(x.l) >> shiftLOW);
494 : : return (h + l) * scaleFIG;
495 : : }
496 : :
497 : : #endif
498 : :
499 : :
500 : : /* convert a 'Rand64' to a 'lua_Unsigned' */
501 : : static lua_Unsigned I2UInt (Rand64 x) {
502 : : return ((lua_Unsigned)trim32(x.h) << 31 << 1) | (lua_Unsigned)trim32(x.l);
503 : : }
504 : :
505 : : /* convert a 'lua_Unsigned' to a 'Rand64' */
506 : : static Rand64 Int2I (lua_Unsigned n) {
507 : : return packI((lu_int32)(n >> 31 >> 1), (lu_int32)n);
508 : : }
509 : :
510 : : #endif /* } */
511 : :
512 : :
513 : : /*
514 : : ** A state uses four 'Rand64' values.
515 : : */
516 : : typedef struct {
517 : : Rand64 s[4];
518 : : } RanState;
519 : :
520 : :
521 : : /*
522 : : ** Project the random integer 'ran' into the interval [0, n].
523 : : ** Because 'ran' has 2^B possible values, the projection can only be
524 : : ** uniform when the size of the interval is a power of 2 (exact
525 : : ** division). Otherwise, to get a uniform projection into [0, n], we
526 : : ** first compute 'lim', the smallest Mersenne number not smaller than
527 : : ** 'n'. We then project 'ran' into the interval [0, lim]. If the result
528 : : ** is inside [0, n], we are done. Otherwise, we try with another 'ran',
529 : : ** until we have a result inside the interval.
530 : : */
531 : 0 : static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n,
532 : : RanState *state) {
533 [ # # ]: 0 : if ((n & (n + 1)) == 0) /* is 'n + 1' a power of 2? */
534 : 0 : return ran & n; /* no bias */
535 : : else {
536 : 0 : lua_Unsigned lim = n;
537 : : /* compute the smallest (2^b - 1) not smaller than 'n' */
538 : 0 : lim |= (lim >> 1);
539 : 0 : lim |= (lim >> 2);
540 : 0 : lim |= (lim >> 4);
541 : 0 : lim |= (lim >> 8);
542 : 0 : lim |= (lim >> 16);
543 : : #if (LUA_MAXUNSIGNED >> 31) >= 3
544 : 0 : lim |= (lim >> 32); /* integer type has more than 32 bits */
545 : : #endif
546 : : lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */
547 : : && lim >= n /* not smaller than 'n', */
548 : : && (lim >> 1) < n); /* and it is the smallest one */
549 [ # # ]: 0 : while ((ran &= lim) > n) /* project 'ran' into [0..lim] */
550 : 0 : ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */
551 : 0 : return ran;
552 : : }
553 : 0 : }
554 : :
555 : :
556 : 0 : static int math_random (lua_State *L) {
557 : : lua_Integer low, up;
558 : : lua_Unsigned p;
559 : 0 : RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1));
560 : 0 : Rand64 rv = nextrand(state->s); /* next pseudo-random value */
561 [ # # # # ]: 0 : switch (lua_gettop(L)) { /* check number of arguments */
562 : : case 0: { /* no arguments */
563 : 0 : lua_pushnumber(L, I2d(rv)); /* float between 0 and 1 */
564 : 0 : return 1;
565 : : }
566 : : case 1: { /* only upper limit */
567 : 0 : low = 1;
568 : 0 : up = luaL_checkinteger(L, 1);
569 [ # # ]: 0 : if (up == 0) { /* single 0 as argument? */
570 : 0 : lua_pushinteger(L, I2UInt(rv)); /* full random integer */
571 : 0 : return 1;
572 : : }
573 : 0 : break;
574 : : }
575 : : case 2: { /* lower and upper limits */
576 : 0 : low = luaL_checkinteger(L, 1);
577 : 0 : up = luaL_checkinteger(L, 2);
578 : 0 : break;
579 : : }
580 : 0 : default: return luaL_error(L, "wrong number of arguments");
581 : : }
582 : : /* random integer in the interval [low, up] */
583 [ # # ]: 0 : luaL_argcheck(L, low <= up, 1, "interval is empty");
584 : : /* project random integer into the interval [0, up - low] */
585 : 0 : p = project(I2UInt(rv), (lua_Unsigned)up - (lua_Unsigned)low, state);
586 : 0 : lua_pushinteger(L, p + (lua_Unsigned)low);
587 : 0 : return 1;
588 : 0 : }
589 : :
590 : :
591 : 810 : static void setseed (lua_State *L, Rand64 *state,
592 : : lua_Unsigned n1, lua_Unsigned n2) {
593 : : int i;
594 : 810 : state[0] = Int2I(n1);
595 : 810 : state[1] = Int2I(0xff); /* avoid a zero state */
596 : 810 : state[2] = Int2I(n2);
597 : 810 : state[3] = Int2I(0);
598 [ + + ]: 13770 : for (i = 0; i < 16; i++)
599 : 12960 : nextrand(state); /* discard initial values to "spread" seed */
600 : 810 : lua_pushinteger(L, n1);
601 : 810 : lua_pushinteger(L, n2);
602 : 810 : }
603 : :
604 : :
605 : : /*
606 : : ** Set a "random" seed. To get some randomness, use the current time
607 : : ** and the address of 'L' (in case the machine does address space layout
608 : : ** randomization).
609 : : */
610 : 810 : static void randseed (lua_State *L, RanState *state) {
611 : 810 : lua_Unsigned seed1 = (lua_Unsigned)time(NULL);
612 : 810 : lua_Unsigned seed2 = (lua_Unsigned)(size_t)L;
613 : 810 : setseed(L, state->s, seed1, seed2);
614 : 810 : }
615 : :
616 : :
617 : 0 : static int math_randomseed (lua_State *L) {
618 : 0 : RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1));
619 [ # # ]: 0 : if (lua_isnone(L, 1)) {
620 : 0 : randseed(L, state);
621 : 0 : }
622 : : else {
623 : 0 : lua_Integer n1 = luaL_checkinteger(L, 1);
624 : 0 : lua_Integer n2 = luaL_optinteger(L, 2, 0);
625 : 0 : setseed(L, state->s, n1, n2);
626 : : }
627 : 0 : return 2; /* return seeds */
628 : : }
629 : :
630 : :
631 : : static const luaL_Reg randfuncs[] = {
632 : : {"random", math_random},
633 : : {"randomseed", math_randomseed},
634 : : {NULL, NULL}
635 : : };
636 : :
637 : :
638 : : /*
639 : : ** Register the random functions and initialize their state.
640 : : */
641 : 810 : static void setrandfunc (lua_State *L) {
642 : 810 : RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0);
643 : 810 : randseed(L, state); /* initialize with a "random" seed */
644 : 810 : lua_pop(L, 2); /* remove pushed seeds */
645 : 810 : luaL_setfuncs(L, randfuncs, 1);
646 : 810 : }
647 : :
648 : : /* }================================================================== */
649 : :
650 : :
651 : : /*
652 : : ** {==================================================================
653 : : ** Deprecated functions (for compatibility only)
654 : : ** ===================================================================
655 : : */
656 : : #if defined(LUA_COMPAT_MATHLIB)
657 : :
658 : : static int math_cosh (lua_State *L) {
659 : : lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
660 : : return 1;
661 : : }
662 : :
663 : : static int math_sinh (lua_State *L) {
664 : : lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
665 : : return 1;
666 : : }
667 : :
668 : : static int math_tanh (lua_State *L) {
669 : : lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
670 : : return 1;
671 : : }
672 : :
673 : : static int math_pow (lua_State *L) {
674 : : lua_Number x = luaL_checknumber(L, 1);
675 : : lua_Number y = luaL_checknumber(L, 2);
676 : : lua_pushnumber(L, l_mathop(pow)(x, y));
677 : : return 1;
678 : : }
679 : :
680 : : static int math_frexp (lua_State *L) {
681 : : int e;
682 : : lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
683 : : lua_pushinteger(L, e);
684 : : return 2;
685 : : }
686 : :
687 : : static int math_ldexp (lua_State *L) {
688 : : lua_Number x = luaL_checknumber(L, 1);
689 : : int ep = (int)luaL_checkinteger(L, 2);
690 : : lua_pushnumber(L, l_mathop(ldexp)(x, ep));
691 : : return 1;
692 : : }
693 : :
694 : : static int math_log10 (lua_State *L) {
695 : : lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
696 : : return 1;
697 : : }
698 : :
699 : : #endif
700 : : /* }================================================================== */
701 : :
702 : :
703 : :
704 : : static const luaL_Reg mathlib[] = {
705 : : {"abs", math_abs},
706 : : {"acos", math_acos},
707 : : {"asin", math_asin},
708 : : {"atan", math_atan},
709 : : {"ceil", math_ceil},
710 : : {"cos", math_cos},
711 : : {"deg", math_deg},
712 : : {"exp", math_exp},
713 : : {"tointeger", math_toint},
714 : : {"floor", math_floor},
715 : : {"fmod", math_fmod},
716 : : {"ult", math_ult},
717 : : {"log", math_log},
718 : : {"max", math_max},
719 : : {"min", math_min},
720 : : {"modf", math_modf},
721 : : {"rad", math_rad},
722 : : {"sin", math_sin},
723 : : {"sqrt", math_sqrt},
724 : : {"tan", math_tan},
725 : : {"type", math_type},
726 : : #if defined(LUA_COMPAT_MATHLIB)
727 : : {"atan2", math_atan},
728 : : {"cosh", math_cosh},
729 : : {"sinh", math_sinh},
730 : : {"tanh", math_tanh},
731 : : {"pow", math_pow},
732 : : {"frexp", math_frexp},
733 : : {"ldexp", math_ldexp},
734 : : {"log10", math_log10},
735 : : #endif
736 : : /* placeholders */
737 : : {"random", NULL},
738 : : {"randomseed", NULL},
739 : : {"pi", NULL},
740 : : {"huge", NULL},
741 : : {"maxinteger", NULL},
742 : : {"mininteger", NULL},
743 : : {NULL, NULL}
744 : : };
745 : :
746 : :
747 : : /*
748 : : ** Open math library
749 : : */
750 : 810 : LUAMOD_API int luaopen_math (lua_State *L) {
751 : 810 : luaL_newlib(L, mathlib);
752 : 810 : lua_pushnumber(L, PI);
753 : 810 : lua_setfield(L, -2, "pi");
754 : 810 : lua_pushnumber(L, (lua_Number)HUGE_VAL);
755 : 810 : lua_setfield(L, -2, "huge");
756 : 810 : lua_pushinteger(L, LUA_MAXINTEGER);
757 : 810 : lua_setfield(L, -2, "maxinteger");
758 : 810 : lua_pushinteger(L, LUA_MININTEGER);
759 : 810 : lua_setfield(L, -2, "mininteger");
760 : 810 : setrandfunc(L);
761 : 810 : return 1;
762 : : }
763 : :
|