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
18static uint64_t state = 0x4d595df4d0f33173;
19static uint64_t multiplier = 6364136223846793005u;
20static uint64_t increment = 1442695040888963407u;
21
22static uint32_t rotr32(uint32_t x, unsigned r) {
23 return x >> r | x << (-r & 31);
24}
25
26var_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
35void pcg32_srand(var_int_t seed) {
36 state = seed + increment;
37 pcg32_rand();
38}
39