1#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
10use rand_core::le::read_u64_into;
11use rand_core::impls::fill_bytes_via_next;
12use rand_core::{RngCore, SeedableRng, Error};
13
14#[allow(missing_copy_implementations)]
24#[derive(Debug, Clone, PartialEq, Eq)]
25#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
26pub struct SplitMix64 {
27 x: u64,
28}
29
30const PHI: u64 = 0x9e3779b97f4a7c15;
31
32impl RngCore for SplitMix64 {
33 #[inline]
34 fn next_u32(&mut self) -> u32 {
35 self.x = self.x.wrapping_add(PHI);
36 let mut z = self.x;
37 z = (z ^ (z >> 33)).wrapping_mul(0x62A9D9ED799705F5);
42 z = (z ^ (z >> 28)).wrapping_mul(0xCB24D0A5C88C35B3);
43 (z >> 32) as u32
44 }
45
46 #[inline]
47 fn next_u64(&mut self) -> u64 {
48 self.x = self.x.wrapping_add(PHI);
49 let mut z = self.x;
50 z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
51 z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb);
52 z ^ (z >> 31)
53 }
54
55 #[inline]
56 fn fill_bytes(&mut self, dest: &mut [u8]) {
57 fill_bytes_via_next(self, dest);
58 }
59
60 #[inline]
61 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
62 self.fill_bytes(dest);
63 Ok(())
64 }
65}
66
67impl SeedableRng for SplitMix64 {
68 type Seed = [u8; 8];
69
70 fn from_seed(seed: [u8; 8]) -> SplitMix64 {
72 let mut state = [0; 1];
73 read_u64_into(&seed, &mut state);
74 SplitMix64 {
75 x: state[0],
76 }
77 }
78
79 fn seed_from_u64(seed: u64) -> SplitMix64 {
81 SplitMix64::from_seed(seed.to_le_bytes())
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn reference() {
91 let mut rng = SplitMix64::seed_from_u64(1477776061723855037);
92 let expected : [u64 ; 50]= [
95 1985237415132408290, 2979275885539914483, 13511426838097143398,
96 8488337342461049707, 15141737807933549159, 17093170987380407015,
97 16389528042912955399, 13177319091862933652, 10841969400225389492,
98 17094824097954834098, 3336622647361835228, 9678412372263018368,
99 11111587619974030187, 7882215801036322410, 5709234165213761869,
100 7799681907651786826, 4616320717312661886, 4251077652075509767,
101 7836757050122171900, 5054003328188417616, 12919285918354108358,
102 16477564761813870717, 5124667218451240549, 18099554314556827626,
103 7603784838804469118, 6358551455431362471, 3037176434532249502,
104 3217550417701719149, 9958699920490216947, 5965803675992506258,
105 12000828378049868312, 12720568162811471118, 245696019213873792,
106 8351371993958923852, 14378754021282935786, 5655432093647472106,
107 5508031680350692005, 8515198786865082103, 6287793597487164412,
108 14963046237722101617, 3630795823534910476, 8422285279403485710,
109 10554287778700714153, 10871906555720704584, 8659066966120258468,
110 9420238805069527062, 10338115333623340156, 13514802760105037173,
111 14635952304031724449, 15419692541594102413,
112 ];
113 for &e in expected.iter() {
114 assert_eq!(rng.next_u64(), e);
115 }
116 }
117
118 #[test]
119 fn next_u32() {
120 let mut rng = SplitMix64::seed_from_u64(10);
121 let expected : [u32 ; 100]= [
124 3930361779, 4016923089, 4113052479, 925926767, 1755287528,
125 802865554, 954171070, 3724185978, 173676273, 1414488795, 12664133,
126 1784889697, 1303817078, 261610523, 941280008, 2571813643,
127 2954453492, 378291111, 2546873158, 3923319175, 645257028,
128 3881821278, 2681538690, 3037029984, 1999958137, 1853970361,
129 2989951788, 2126166628, 839962987, 3989679659, 3656977858,
130 684284364, 1673258011, 170979192, 3037622326, 1600748179,
131 1780764218, 1141430714, 4139736875, 3336905707, 2262051600,
132 3830850262, 2430765325, 1073032139, 1668888979, 2716938970,
133 4102420032, 40305196, 386350562, 2754480591, 622869439, 2129598760,
134 2306038241, 4218338739, 412298926, 3453855056, 3061469690,
135 4284292697, 994843708, 1591016681, 414726151, 1238182607, 18073498,
136 1237631493, 351884714, 2347486264, 2488990876, 802846256, 645670443,
137 957607012, 3126589776, 1966356370, 3036485766, 868696717,
138 2808613630, 2070968151, 1025536863, 1743949425, 466212687,
139 2994327271, 209776458, 1246125124, 3344380309, 2203947859,
140 968313105, 2805485302, 197484837, 3472483632, 3931823935,
141 3288490351, 4165666529, 3671080416, 689542830, 1272555356,
142 1039141475, 3984640460, 4142959054, 2252788890, 2459379590,
143 991872507,
144 ];
145 for &e in expected.iter() {
146 assert_eq!(rng.next_u32(), e);
147 }
148 }
149}