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