weiss_core/
util.rs

1/// Deterministic xorshift64* RNG for reproducibility.
2#[derive(Clone, Copy, Debug, Hash)]
3pub struct Rng64 {
4    state: u64,
5}
6
7impl Rng64 {
8    pub fn new(seed: u64) -> Self {
9        let mut s = seed;
10        if s == 0 {
11            s = 0x9E3779B97F4A7C15;
12        }
13        Self { state: s }
14    }
15
16    pub fn next_u64(&mut self) -> u64 {
17        // xorshift64*
18        let mut x = self.state;
19        x ^= x >> 12;
20        x ^= x << 25;
21        x ^= x >> 27;
22        self.state = x;
23        x.wrapping_mul(0x2545F4914F6CDD1D)
24    }
25
26    pub fn next_u32(&mut self) -> u32 {
27        (self.next_u64() >> 32) as u32
28    }
29
30    pub fn state(&self) -> u64 {
31        self.state
32    }
33
34    pub fn next_bool(&mut self) -> bool {
35        (self.next_u64() & 1) == 1
36    }
37
38    pub fn gen_range(&mut self, upper: usize) -> usize {
39        if upper == 0 {
40            return 0;
41        }
42        (self.next_u64() as usize) % upper
43    }
44
45    pub fn shuffle<T>(&mut self, slice: &mut [T]) {
46        for i in (1..slice.len()).rev() {
47            let j = self.gen_range(i + 1);
48            slice.swap(i, j);
49        }
50    }
51}