1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//! The deterministic generator behind [`Distribution::sample`](super::Distribution::sample)
//! (SplitMix64): seeded and reproducible, so Monte-Carlo sanity checks of
//! exact results are repeatable.
/// A deterministic pseudo-random generator (SplitMix64). Not
/// cryptographic; seeded, reproducible, and good enough for Monte-Carlo
/// sanity checks of exact results.
#[derive(Clone, Debug)]
pub struct Rng(u64);
impl Rng {
/// A generator with the given seed.
pub fn new(seed: u64) -> Self {
Rng(seed)
}
/// The next 64 random bits.
pub fn next_u64(&mut self) -> u64 {
self.0 = self.0.wrapping_add(0x9E37_79B9_7F4A_7C15);
let mut z = self.0;
z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
z ^ (z >> 31)
}
/// Uniform in `[0, 1)` with 53 random bits.
pub fn next_f64(&mut self) -> f64 {
(self.next_u64() >> 11) as f64 / (1u64 << 53) as f64
}
/// Uniform in `0..n` (`n > 0`; `0` for `n == 0`).
pub fn below(&mut self, n: usize) -> usize {
if n == 0 {
return 0;
}
(self.next_u64() % n as u64) as usize
}
}