1 | // This file is part of SmallBASIC |
---|---|
2 | // |
3 | // random number generator, see: |
4 | // https://en.wikipedia.org/wiki/Permuted_congruential_generator |
5 | // https://www.pcg-random.org/download.html |
6 | // |
7 | // This program is distributed under the terms of the GPL v2.0 or later |
8 | // Download the GNU Public License (GPL) from www.gnu.org |
9 | // |
10 | // Copyright(C) 2021 Chris Warren-Smith |
11 | |
12 | #include "config.h" |
13 | |
14 | #include "common/sys.h" |
15 | #include <stdint.h> |
16 | #include <limits.h> |
17 | |
18 | static uint64_t state = 0x4d595df4d0f33173; |
19 | static uint64_t multiplier = 6364136223846793005u; |
20 | static uint64_t increment = 1442695040888963407u; |
21 | |
22 | static uint32_t rotr32(uint32_t x, unsigned r) { |
23 | return x >> r | x << (-r & 31); |
24 | } |
25 | |
26 | var_num_t pcg32_rand() { |
27 | uint64_t x = state; |
28 | unsigned count = (unsigned)(x >> 59); |
29 | state = x * multiplier + increment; |
30 | x ^= x >> 18; |
31 | int32_t r = rotr32((uint32_t)(x >> 27), count); |
32 | return ((var_num_t)abs(r)) / (INT_MAX + 1.0); |
33 | } |
34 | |
35 | void pcg32_srand(var_int_t seed) { |
36 | state = seed + increment; |
37 | pcg32_rand(); |
38 | } |
39 |