devela/num/rand/lgc/
u16.rs
1use crate::{ConstDefault, Own};
7
8#[derive(Clone, Debug, PartialEq, Eq)]
13pub struct Lgc16(u16);
14
15impl Default for Lgc16 {
17 fn default() -> Self {
18 Self::DEFAULT
19 }
20}
21impl ConstDefault for Lgc16 {
23 const DEFAULT: Self = Self::new(Self::DEFAULT_SEED);
24}
25
26impl Lgc16 {
28 const DEFAULT_SEED: u16 = 0xDEFA;
29
30 const MUL: u16 = 25173;
32 const INC: u16 = 13849;
34 const MOD: u16 = 65535;
36}
37
38impl Lgc16 {
39 #[must_use]
41 pub const fn new(seed: u16) -> Self {
42 Self(seed)
43 }
44
45 pub fn reseed(&mut self, seed: u16) {
47 self.0 = seed;
48 }
49
50 #[must_use]
51 pub const fn inner_state(self) -> u16 {
53 self.0
54 }
55 pub const fn from_state(state: u16) -> Self {
57 Self(state)
58 }
59
60 #[must_use]
62 pub const fn current_u16(&self) -> u16 {
63 self.0
64 }
65 #[must_use]
67 pub 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
72 #[must_use]
74 pub const fn peek_next_state(&self) -> Self {
75 let x = (Self::MUL.wrapping_mul(self.0).wrapping_add(Self::INC)) & Self::MOD;
76 Self(x)
77 }
78
79 pub const fn own_next_u16(self) -> Own<Self, u16> {
81 let s = self.peek_next_state();
82 let v = s.current_u16();
83 Own::new(s, v)
84 }
85}
86
87impl Lgc16 {
89 pub const fn new1_u16(seed: u16) -> Self {
93 Self::new(seed)
94 }
95
96 #[must_use]
100 pub const fn new2_u8(seeds: [u8; 2]) -> Self {
101 Self::new(u16::from_le_bytes(seeds))
102 }
103}
104
105#[cfg(all(feature = "dep_rand_core", feature = "join"))]
106#[cfg_attr(feature = "nightly_doc", doc(cfg(all(feature = "dep_rand_core", feature = "join"))))]
107mod impl_rand {
108 use crate::_dep::rand_core::{RngCore, SeedableRng};
109 use crate::{Cast, Lgc16};
110
111 impl RngCore for Lgc16 {
112 fn next_u32(&mut self) -> u32 {
114 Cast::<u32>::from_u16_le([self.next_u16(), self.next_u16()])
115 }
116 fn next_u64(&mut self) -> u64 {
118 Cast::<u64>::from_u16_le([
119 self.next_u16(),
120 self.next_u16(),
121 self.next_u16(),
122 self.next_u16(),
123 ])
124 }
125 fn fill_bytes(&mut self, dest: &mut [u8]) {
126 let mut i = 0;
127 while i < dest.len() {
128 let random_u16 = self.next_u16();
129 let bytes = random_u16.to_le_bytes();
130 let remaining = dest.len() - i;
131
132 if remaining >= 2 {
133 dest[i] = bytes[0];
134 dest[i + 1] = bytes[1];
135 i += 2;
136 } else {
137 dest[i] = bytes[0];
138 i += 1;
139 }
140 }
141 }
142 }
143
144 impl SeedableRng for Lgc16 {
145 type Seed = [u8; 2];
146
147 fn from_seed(seed: Self::Seed) -> Self {
150 Self::new(u16::from_le_bytes(seed))
151 }
152 }
153}