rand_pcg/
pcg64.rs
1use core::fmt;
14use core::mem::transmute;
15use rand_core::{RngCore, SeedableRng, Error, le, impls};
16
17const MULTIPLIER: u64 = 6364136223846793005;
19
20#[derive(Clone)]
33#[cfg_attr(feature="serde1", derive(Serialize,Deserialize))]
34pub struct Lcg64Xsh32 {
35 state: u64,
36 increment: u64,
37}
38
39pub type Pcg32 = Lcg64Xsh32;
41
42impl Lcg64Xsh32 {
43 pub fn new(state: u64, stream: u64) -> Self {
50 let increment = (stream << 1) | 1;
52 Lcg64Xsh32::from_state_incr(state, increment)
53 }
54
55 #[inline]
56 fn from_state_incr(state: u64, increment: u64) -> Self {
57 let mut pcg = Lcg64Xsh32 { state, increment };
58 pcg.state = pcg.state.wrapping_add(pcg.increment);
60 pcg.step();
61 pcg
62 }
63
64 #[inline]
65 fn step(&mut self) {
66 self.state = self.state
68 .wrapping_mul(MULTIPLIER)
69 .wrapping_add(self.increment);
70 }
71}
72
73impl fmt::Debug for Lcg64Xsh32 {
75 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76 write!(f, "Lcg64Xsh32 {{}}")
77 }
78}
79
80impl SeedableRng for Lcg64Xsh32 {
83 type Seed = [u8; 16];
84
85 fn from_seed(seed: Self::Seed) -> Self {
86 let mut seed_u64 = [0u64; 2];
87 le::read_u64_into(&seed, &mut seed_u64);
88
89 Lcg64Xsh32::from_state_incr(seed_u64[0], seed_u64[1] | 1)
91 }
92}
93
94impl RngCore for Lcg64Xsh32 {
95 #[inline]
96 fn next_u32(&mut self) -> u32 {
97 let state = self.state;
98 self.step();
99
100 const ROTATE: u32 = 59; const XSHIFT: u32 = 18; const SPARE: u32 = 27; let rot = (state >> ROTATE) as u32;
107 let xsh = (((state >> XSHIFT) ^ state) >> SPARE) as u32;
108 xsh.rotate_right(rot)
109 }
110
111 #[inline]
112 fn next_u64(&mut self) -> u64 {
113 impls::next_u64_via_u32(self)
114 }
115
116 #[inline]
117 fn fill_bytes(&mut self, dest: &mut [u8]) {
118 let mut left = dest;
120 while left.len() >= 4 {
121 let (l, r) = {left}.split_at_mut(4);
122 left = r;
123 let chunk: [u8; 4] = unsafe {
124 transmute(self.next_u32().to_le())
125 };
126 l.copy_from_slice(&chunk);
127 }
128 let n = left.len();
129 if n > 0 {
130 let chunk: [u8; 4] = unsafe {
131 transmute(self.next_u32().to_le())
132 };
133 left.copy_from_slice(&chunk[..n]);
134 }
135 }
136
137 #[inline]
138 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
139 Ok(self.fill_bytes(dest))
140 }
141}
142
143#[cfg(test)]
144mod tests {
145 use ::rand_core::{RngCore, SeedableRng};
146 use super::*;
147
148 #[test]
149 fn test_lcg64xsh32_construction() {
150 let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16];
152 let mut rng1 = Lcg64Xsh32::from_seed(seed);
153 assert_eq!(rng1.next_u64(), 1204678643940597513);
154
155 let mut rng2 = Lcg64Xsh32::from_rng(&mut rng1).unwrap();
156 assert_eq!(rng2.next_u64(), 12384929573776311845);
157
158 let mut rng3 = Lcg64Xsh32::seed_from_u64(0);
159 assert_eq!(rng3.next_u64(), 18195738587432868099);
160
161 let mut rng4 = Pcg32::seed_from_u64(0);
163 assert_eq!(rng4.next_u64(), 18195738587432868099);
164 }
165
166 #[test]
167 fn test_lcg64xsh32_true_values() {
168 let mut rng = Lcg64Xsh32::new(42, 54);
170
171 let mut results = [0u32; 6];
172 for i in results.iter_mut() { *i = rng.next_u32(); }
173 let expected: [u32; 6] = [0xa15c02b7, 0x7b47f409, 0xba1d3330,
174 0x83d2f293, 0xbfa4784b, 0xcbed606e];
175 assert_eq!(results, expected);
176 }
177
178 #[cfg(feature="serde1")]
179 #[test]
180 fn test_lcg64xsh32_serde() {
181 use bincode;
182 use std::io::{BufWriter, BufReader};
183
184 let mut rng = Lcg64Xsh32::seed_from_u64(0);
185
186 let buf: Vec<u8> = Vec::new();
187 let mut buf = BufWriter::new(buf);
188 bincode::serialize_into(&mut buf, &rng).expect("Could not serialize");
189
190 let buf = buf.into_inner().unwrap();
191 let mut read = BufReader::new(&buf[..]);
192 let mut deserialized: Lcg64Xsh32 = bincode::deserialize_from(&mut read).expect("Could not deserialize");
193
194 assert_eq!(rng.state, deserialized.state);
195
196 for _ in 0..16 {
197 assert_eq!(rng.next_u64(), deserialized.next_u64());
198 }
199 }
200}