| 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 | 
