clock_rand/fast/
splitmix64.rs1use crate::traits::Rng;
7
8#[derive(Debug, Clone)]
14pub struct SplitMix64 {
15 state: u64,
16}
17
18impl SplitMix64 {
19 #[inline]
21 pub fn new(seed: u64) -> Self {
22 Self { state: seed }
23 }
24
25 #[inline(always)]
27 pub fn next_u64(&mut self) -> u64 {
28 self.state = self.state.wrapping_add(0x9e3779b97f4a7c15);
29 let mut z = self.state;
30 z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
31 z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb);
32 z ^ (z >> 31)
33 }
34
35 #[inline]
37 pub fn next_u32(&mut self) -> u32 {
38 (self.next_u64() >> 32) as u32
39 }
40
41 #[inline]
43 pub fn fill_bytes(&mut self, dest: &mut [u8]) {
44 let mut chunks = dest.chunks_exact_mut(8);
45 for chunk in chunks.by_ref() {
46 let value = self.next_u64();
47 chunk.copy_from_slice(&value.to_le_bytes());
48 }
49 let remainder = chunks.into_remainder();
50 if !remainder.is_empty() {
51 let value = self.next_u64();
52 let bytes = value.to_le_bytes();
53 remainder.copy_from_slice(&bytes[..remainder.len()]);
54 }
55 }
56
57 pub fn seed_xoshiro256(&mut self) -> [u64; 4] {
59 [
60 self.next_u64(),
61 self.next_u64(),
62 self.next_u64(),
63 self.next_u64(),
64 ]
65 }
66
67 pub fn seed_pcg64(&mut self) -> [u64; 2] {
69 [self.next_u64(), self.next_u64()]
70 }
71}
72
73impl Rng for SplitMix64 {
74 #[inline]
75 fn next_u32(&mut self) -> u32 {
76 self.next_u32()
77 }
78
79 #[inline]
80 fn next_u64(&mut self) -> u64 {
81 self.next_u64()
82 }
83
84 #[inline]
85 fn fill_bytes(&mut self, dest: &mut [u8]) {
86 self.fill_bytes(dest)
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn test_splitmix64_deterministic() {
96 let mut rng1 = SplitMix64::new(12345);
97 let mut rng2 = SplitMix64::new(12345);
98
99 for _ in 0..100 {
100 assert_eq!(rng1.next_u64(), rng2.next_u64());
101 }
102 }
103
104 #[test]
105 fn test_splitmix64_fill_bytes() {
106 let mut rng = SplitMix64::new(42);
107 let mut buf = [0u8; 32];
108 rng.fill_bytes(&mut buf);
109
110 assert!(!buf.iter().all(|&b| b == 0));
112 }
113}