Pseudo-random numbers/Combined recursive generator MRG32k3a: Difference between revisions
Content deleted Content added
Line 314: | Line 314: | ||
for (i = 0; i < 5; i++) { |
for (i = 0; i < 5; i++) { |
||
printf("%d: %d\n", i, counts[i]); |
printf("%d: %d\n", i, counts[i]); |
||
} |
|||
return 0; |
|||
}</lang> |
|||
{{out}} |
|||
<pre>1459213977 |
|||
2827710106 |
|||
4245671317 |
|||
3877608661 |
|||
2595287583 |
|||
0: 20002 |
|||
1: 20060 |
|||
2: 19948 |
|||
3: 20059 |
|||
4: 19931</pre> |
|||
=={{header|C++}}== |
|||
{{trans|C}} |
|||
<lang cpp>#include <array> |
|||
#include <iostream> |
|||
int64_t mod(int64_t x, int64_t y) { |
|||
int64_t m = x % y; |
|||
if (m < 0) { |
|||
if (y < 0) { |
|||
return m - y; |
|||
} else { |
|||
return m + y; |
|||
} |
|||
} |
|||
return m; |
|||
} |
|||
class RNG { |
|||
private: |
|||
// First generator |
|||
const std::array<int64_t, 3> a1{ 0, 1403580, -810728 }; |
|||
const int64_t m1 = (1LL << 32) - 209; |
|||
std::array<int64_t, 3> x1; |
|||
// Second generator |
|||
const std::array<int64_t, 3> a2{ 527612, 0, -1370589 }; |
|||
const int64_t m2 = (1LL << 32) - 22853; |
|||
std::array<int64_t, 3> x2; |
|||
// other |
|||
const int64_t d = (1LL << 32) - 209 + 1; // m1 + 1 |
|||
public: |
|||
void seed(int64_t state) { |
|||
x1 = { state, 0, 0 }; |
|||
x2 = { state, 0, 0 }; |
|||
} |
|||
int64_t next_int() { |
|||
int64_t x1i = mod((a1[0] * x1[0] + a1[1] * x1[1] + a1[2] * x1[2]), m1); |
|||
int64_t x2i = mod((a2[0] * x2[0] + a2[1] * x2[1] + a2[2] * x2[2]), m2); |
|||
int64_t z = mod(x1i - x2i, m1); |
|||
// keep last three values of the first generator |
|||
x1 = { x1i, x1[0], x1[1] }; |
|||
// keep last three values of the second generator |
|||
x2 = { x2i, x2[0], x2[1] }; |
|||
return z + 1; |
|||
} |
|||
double next_float() { |
|||
return static_cast<double>(next_int()) / d; |
|||
} |
|||
}; |
|||
int main() { |
|||
RNG rng; |
|||
rng.seed(1234567); |
|||
std::cout << rng.next_int() << '\n'; |
|||
std::cout << rng.next_int() << '\n'; |
|||
std::cout << rng.next_int() << '\n'; |
|||
std::cout << rng.next_int() << '\n'; |
|||
std::cout << rng.next_int() << '\n'; |
|||
std::cout << '\n'; |
|||
std::array<int, 5> counts{ 0, 0, 0, 0, 0 }; |
|||
rng.seed(987654321); |
|||
for (size_t i = 0; i < 100000; i++) { |
|||
auto value = floor(rng.next_float() * 5.0); |
|||
counts[value]++; |
|||
} |
|||
for (size_t i = 0; i < counts.size(); i++) { |
|||
std::cout << i << ": " << counts[i] << '\n'; |
|||
} |
} |
||