1use rand_core::{RngCore, Error, SeedableRng, le};
2
3#[cfg(feature = "serde1")]
4use serde::{Deserialize, Serialize};
5
6const MULTIPLIER: u32 = 3487286589; #[derive(Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
18pub struct Mwc128XXA32 {
19 pub(crate) x1: u32,
20 pub(crate) x2: u32,
21 pub(crate) x3: u32,
22 pub(crate) c: u32,
23}
24
25impl Mwc128XXA32 {
26 pub fn new(k1: u32, k2: u32) -> Self {
28 Mwc128XXA32::from_state_incr(k1, k2, 0xcafef00d, 0xd15ea5e5)
31 }
32
33 #[inline]
34 fn from_state_incr(x1: u32, x2: u32, x3: u32, c: u32) -> Self {
35 let mut pcg = Mwc128XXA32 { x1, x2, x3, c };
36 pcg.gen6();
38 pcg
39 }
40
41 pub fn next(&mut self) -> u32 {
42 self.step()
43 }
44
45 #[inline]
46 fn step(&mut self) -> u32 {
47 let (low, hi) = multiply(self.x3);
49 let result = permute(self.x1, self.x2, self.x3, self.c, low, hi);
50 let (x1, b) = low.overflowing_add(self.c);
51 self.x3 = self.x2;
52 self.x2 = self.x1;
53 self.x1 = x1;
54 self.c = hi.wrapping_add(b as u32);
55 result
56 }
57
58 #[inline]
59 fn gen6(&mut self) -> [u32; 6] {
60 let mut result = [0; 6];
63 let (low, hi) = multiply(self.x3);
64 result[0] = permute(self.x1, self.x2, self.x3, self.c, low, hi);
65 let (r1, b) = low.overflowing_add(self.c);
66 let c = hi.wrapping_add(b as u32);
67 let (low, hi) = multiply(self.x2);
68 result[1] = permute(r1, self.x1, self.x2, c, low, hi);
69 let (r2, b) = low.overflowing_add(c);
70 let c = hi.wrapping_add(b as u32);
71 let (low, hi) = multiply(self.x1);
72 result[2] = permute(r2, r1, self.x1, c, low, hi);
73 let (r3, b) = low.overflowing_add(c);
74 let c = hi.wrapping_add(b as u32);
75
76 let (low, hi) = multiply(r1);
77 result[3] = permute(r3, r2, r1, c, low, hi);
78 let (r1, b) = low.overflowing_add(c);
79 let c = hi.wrapping_add(b as u32);
80 let (low, hi) = multiply(r2);
81 result[4] = permute(r1, r3, r2, c, low, hi);
82 let (r2, b) = low.overflowing_add(c);
83 let c = hi.wrapping_add(b as u32);
84 let (low, hi) = multiply(r3);
85 result[5] = permute(r2, r1, r3, c, low, hi);
86 let (r3, b) = low.overflowing_add(c);
87 let c = hi.wrapping_add(b as u32);
88
89 self.c = c;
90 self.x1 = r3;
91 self.x2 = r2;
92 self.x3 = r1;
93 return result;
94 }
95}
96
97
98impl SeedableRng for Mwc128XXA32 {
101 type Seed = [u8; 16];
102
103 fn from_seed(seed: Self::Seed) -> Self {
104 let mut seed_u32 = [0u32; 4];
105 le::read_u32_into(&seed, &mut seed_u32);
106 let c = (seed_u32[0] & 0x3fff_fff8) | 5;
108 let x3 = (seed_u32[3] << 2) | 1;
110 Mwc128XXA32::from_state_incr(seed_u32[1], seed_u32[2], x3, c)
111 }
112}
113
114impl RngCore for Mwc128XXA32 {
115 #[inline]
116 fn next_u32(&mut self) -> u32 {
117 self.step() as u32
118 }
119
120 #[inline]
121 fn next_u64(&mut self) -> u64 {
122 let result = self.step() as u64;
123 return (result << 32) | (self.step() as u64);
124 }
125
126 #[inline]
127 fn fill_bytes(&mut self, dest: &mut [u8]) {
128 let mut dest_chunks = dest.chunks_exact_mut(6 * 4);
129 for mut dest_chunk in &mut dest_chunks {
130 for &num in self.gen6().iter() {
131 let (l, r) = dest_chunk.split_at_mut(4);
132 l.copy_from_slice(&num.to_le_bytes());
133 dest_chunk = r;
134 }
135 }
136 for dest_chunk in dest_chunks.into_remainder().chunks_mut(4) {
137 dest_chunk.copy_from_slice(&self.step().to_le_bytes()[..dest_chunk.len()]);
138 }
139 }
140
141 #[inline(always)]
142 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
143 self.fill_bytes(dest);
144 Ok(())
145 }
146}
147
148#[inline(always)]
149fn multiply(val: u32) -> (u32, u32) {
150 let t = (val as u64).wrapping_mul(MULTIPLIER as u64);
151 return (t as u32, (t >> 32) as u32);
152}
153
154#[inline(always)]
155fn permute(x1: u32, x2: u32, x3: u32, _c: u32, _low: u32, hi: u32) -> u32 {
156 (x3 ^ x2).wrapping_add(x1 ^ hi)
157}