|
2 | 2 | #include "jsvalue.h"
|
3 | 3 | #include "jsbuiltin.h"
|
4 | 4 |
|
5 |
| -#if defined(_MSC_VER) && (_MSC_VER < 1700) /* VS2012 has stdint.h */ |
6 |
| -typedef unsigned int uint32_t; |
7 |
| -typedef unsigned __int64 uint64_t; |
8 |
| -#else |
9 |
| -#include <stdint.h> |
10 |
| -#endif |
11 |
| - |
12 | 5 | #include <time.h>
|
13 | 6 |
|
14 | 7 | static double jsM_round(double x)
|
@@ -85,21 +78,23 @@ static void Math_pow(js_State *J)
|
85 | 78 |
|
86 | 79 | static void Math_random(js_State *J)
|
87 | 80 | {
|
88 |
| - /* Lehmer generator with a=48271 and m=2^31-1 */ |
89 |
| - /* Park & Miller (1988). Random Number Generators: Good ones are hard to find. */ |
90 |
| - J->seed = (uint64_t) J->seed * 48271 % 0x7fffffff; |
91 |
| - js_pushnumber(J, (double) J->seed / 0x7fffffff); |
| 81 | + // A Lehmer (MLCG) RNG using doubles. |
| 82 | + // Parameters from Pierre l'Ecuyer's paper: |
| 83 | + // https://www.ams.org/journals/mcom/1999-68-225/S0025-5718-99-00996-5/S0025-5718-99-00996-5.pdf |
| 84 | + // m = 2^35 - 31 |
| 85 | + J->seed = J->seed * fmod(200105.0, 34359738337.0); |
| 86 | + js_pushnumber(J, J->seed / 34359738337.0); |
92 | 87 | }
|
93 | 88 |
|
94 | 89 | static void Math_init_random(js_State *J)
|
95 | 90 | {
|
96 | 91 | /* Pick initial seed by scrambling current time with Xorshift. */
|
97 | 92 | /* Marsaglia (2003). Xorshift RNGs. */
|
98 |
| - J->seed = time(0) + 123; |
99 |
| - J->seed ^= J->seed << 13; |
100 |
| - J->seed ^= J->seed >> 17; |
101 |
| - J->seed ^= J->seed << 5; |
102 |
| - J->seed %= 0x7fffffff; |
| 93 | + unsigned int seed = time(0) + 123; |
| 94 | + seed ^= seed << 13; |
| 95 | + seed ^= seed >> 17; |
| 96 | + seed ^= seed << 5; |
| 97 | + J->seed = seed; |
103 | 98 | }
|
104 | 99 |
|
105 | 100 | static void Math_round(js_State *J)
|
|
0 commit comments