devela/num/rand/lgc/
u16.rs1use crate::{ConstDefault, Own};
7
8#[doc = crate::TAG_RAND!()]
9#[derive(Clone, Debug, PartialEq, Eq)]
14pub struct Lgc16(u16);
15
16impl Default for Lgc16 {
18 fn default() -> Self {
19 Self::DEFAULT
20 }
21}
22impl ConstDefault for Lgc16 {
24 const DEFAULT: Self = Self::new(Self::DEFAULT_SEED);
25}
26
27impl Lgc16 {
29 const DEFAULT_SEED: u16 = 0xDEFA;
30
31 const MUL: u16 = 25173;
33 const INC: u16 = 13849;
35 const MOD: u16 = 65535;
37}
38
39impl Lgc16 {
40 #[must_use]
42 pub const fn new(seed: u16) -> Self {
43 Self(seed)
44 }
45
46 pub fn reseed(&mut self, seed: u16) {
48 self.0 = seed;
49 }
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
61 #[must_use]
63 pub const fn current_u16(&self) -> u16 {
64 self.0
65 }
66 #[must_use]
68 pub fn next_u16(&mut self) -> u16 {
69 self.0 = (Self::MUL.wrapping_mul(self.0).wrapping_add(Self::INC)) & Self::MOD;
70 self.0
71 }
72
73 #[must_use]
75 pub const fn peek_next_state(&self) -> Self {
76 let x = (Self::MUL.wrapping_mul(self.0).wrapping_add(Self::INC)) & Self::MOD;
77 Self(x)
78 }
79
80 pub const fn own_next_u16(self) -> Own<Self, u16> {
82 let s = self.peek_next_state();
83 let v = s.current_u16();
84 Own::new(s, v)
85 }
86}
87
88impl Lgc16 {
90 pub const fn new1_u16(seed: u16) -> Self {
94 Self::new(seed)
95 }
96
97 #[must_use]
101 pub const fn new2_u8(seeds: [u8; 2]) -> Self {
102 Self::new(u16::from_le_bytes(seeds))
103 }
104}
105
106#[cfg(all(feature = "dep_rand_core", feature = "join"))]
107#[cfg_attr(nightly_doc, doc(cfg(all(feature = "dep_rand_core", feature = "join"))))]
108mod impl_rand {
109 use crate::_dep::rand_core::{RngCore, SeedableRng};
110 use crate::{Cast, Lgc16};
111
112 impl RngCore for Lgc16 {
113 fn next_u32(&mut self) -> u32 {
115 Cast::<u32>::from_u16_le([self.next_u16(), self.next_u16()])
116 }
117 fn next_u64(&mut self) -> u64 {
119 Cast::<u64>::from_u16_le([
120 self.next_u16(),
121 self.next_u16(),
122 self.next_u16(),
123 self.next_u16(),
124 ])
125 }
126 fn fill_bytes(&mut self, dest: &mut [u8]) {
127 let mut i = 0;
128 while i < dest.len() {
129 let random_u16 = self.next_u16();
130 let bytes = random_u16.to_le_bytes();
131 let remaining = dest.len() - i;
132
133 if remaining >= 2 {
134 dest[i] = bytes[0];
135 dest[i + 1] = bytes[1];
136 i += 2;
137 } else {
138 dest[i] = bytes[0];
139 i += 1;
140 }
141 }
142 }
143 }
144
145 impl SeedableRng for Lgc16 {
146 type Seed = [u8; 2];
147
148 fn from_seed(seed: Self::Seed) -> Self {
151 Self::new(u16::from_le_bytes(seed))
152 }
153 }
154}