devela/num/prob/rand/prng/lcg/
u16.rs1use crate::{Cast, ConstInit, Own};
7use crate::{Infallible, InfallibleResult, RandQualities, RandSeedable, RandTry};
8
9#[doc = crate::_tags!(rand)]
10#[doc = concat!["A 16-bit ", crate::_ABBR_LCG!(), " ", crate::_ABBR_PRNG!(), "."]]
11#[doc = crate::_doc_meta!{location("num/prob/rand")}]
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
15pub struct Lcg16(u16);
16
17impl Default for Lcg16 {
19 fn default() -> Self {
20 Self::INIT
21 }
22}
23impl ConstInit for Lcg16 {
25 const INIT: Self = Self::new(Self::DEFAULT_SEED);
26}
27
28impl Lcg16 {
30 #[doc(hidden)]
31 pub const DEFAULT_SEED: u16 = 0xDEFA;
32
33 const MUL: u16 = 25173;
35 const INC: u16 = 13849;
37 const MOD: u16 = 65535;
39}
40
41impl Lcg16 {
42 #[must_use]
44 pub const fn new(seed: u16) -> Self {
45 Self(seed)
46 }
47 pub const fn reseed(&mut self, seed: u16) {
49 self.0 = seed;
50 }
51 #[must_use]
52 pub const fn inner_state(self) -> u16 {
54 self.0
55 }
56 pub const fn from_state(state: u16) -> Self {
58 Self(state)
59 }
60 #[must_use]
62 pub const fn current_u16(&self) -> u16 {
63 self.0
64 }
65 #[must_use]
67 pub const fn next_u16(&mut self) -> u16 {
68 self.0 = (Self::MUL.wrapping_mul(self.0).wrapping_add(Self::INC)) & Self::MOD;
69 self.0
70 }
71 #[must_use]
73 pub const fn peek_next_state(&self) -> Self {
74 let x = (Self::MUL.wrapping_mul(self.0).wrapping_add(Self::INC)) & Self::MOD;
75 Self(x)
76 }
77 pub const fn own_next_u16(self) -> Own<Self, u16> {
79 let s = self.peek_next_state();
80 let v = s.current_u16();
81 Own::new(s, v)
82 }
83 pub const fn fill_bytes(&mut self, buffer: &mut [u8]) {
85 let mut i = 0;
86 while i < buffer.len() {
87 let random_u16 = self.next_u16();
88 let bytes = random_u16.to_le_bytes();
89 let remaining = buffer.len() - i;
90 if remaining >= 2 {
91 buffer[i] = bytes[0];
92 buffer[i + 1] = bytes[1];
93 i += 2;
94 } else {
95 buffer[i] = bytes[0];
96 i += 1;
97 }
98 }
99 }
100}
101impl Lcg16 {
103 pub const fn new1_u16(seed: u16) -> Self {
107 Self::new(seed)
108 }
109 #[must_use]
113 pub const fn new2_u8(seeds: [u8; 2]) -> Self {
114 Self::new(u16::from_le_bytes(seeds))
115 }
116
117 pub const fn next_u32(&mut self) -> u32 {
119 Cast::<u32>::from_u16_le([self.next_u16(), self.next_u16()])
120 }
121 pub const fn next_u64(&mut self) -> u64 {
123 Cast::<u64>::from_u16_le([
124 self.next_u16(),
125 self.next_u16(),
126 self.next_u16(),
127 self.next_u16(),
128 ])
129 }
130}
131
132crate::items! {
133 impl RandTry for Lcg16 {
134 type Error = Infallible;
135 const RAND_OUTPUT_BITS: u32 = 64;
136 const RAND_STATE_BITS: u32 = 64;
137 const RAND_QUALITIES: RandQualities = RandQualities::WEAK_PRNG;
138 fn rand_try_next_u16(&mut self) -> InfallibleResult<u16> { Ok(self.next_u16()) }
139 fn rand_try_next_u32(&mut self) -> InfallibleResult<u32> { Ok(self.next_u32()) }
140 fn rand_try_next_u64(&mut self) -> InfallibleResult<u64> { Ok(self.next_u64()) }
141 fn rand_try_fill_bytes(&mut self, buffer: &mut [u8]) -> InfallibleResult<()> {
142 self.fill_bytes(buffer);
143 Ok(())
144 }
145 }
146 impl RandSeedable for Lcg16 {
147 type RandSeed = [u8; 2];
148 #[inline(always)]
149 fn rand_from_seed(seed: Self::RandSeed) -> Self { Self::new(u16::from_le_bytes(seed)) }
150 }
151}
152crate::__impl_dep_rand_core!(Lcg16);