#[derive(Debug)]
pub struct Rng {
state: u32,
mask: u32,
tap: u32,
f32_max: f32,
}
const DEFAULT_VALUE: u32 = 0b01100010101011110110101010101011;
impl Rng {
pub fn new(bit_count: u32, initial_state: u32) -> Self {
let bit_count = bit_count.clamp(3, 32);
let mask = ((1u64 << bit_count) - 1) as u32;
let state = if (initial_state & mask) == 0 {
DEFAULT_VALUE & mask
} else {
initial_state & mask
};
Self {
state,
mask,
tap: get_tap(bit_count),
f32_max: libm::powf(2.0, bit_count as f32 ),
}
}
pub fn next_u32(&mut self) -> u32 {
let lsb = self.state & 1; self.state = xor_with_tap(self.state >> 1, self.tap, lsb);
self.state & self.mask
}
pub fn next_f32(&mut self) -> f32 {
self.next_u32() as f32 / self.f32_max
}
}
#[inline(always)]
fn xor_with_tap(value: u32, tap: u32, bit: u32) -> u32 {
value ^ (tap & (bit * 0xFFFFFFFF))
}
fn get_tap(bit_count: u32) -> u32 {
match bit_count {
3 => 0b110,
4 => 0b1100,
5 => 0b10100,
6 => 0b110000,
7 => 0b1100000,
8 => 0b10111000,
9 => 0b100010000,
10 => 0b1001000000,
11 => 0b10100000000,
12 => 0b111000001000,
13 => 0b1110010000000,
14 => 0b11100000000010,
15 => 0b110000000000000,
16 => 0b1101000000001000,
17 => 0b10010000000000000,
18 => 0b100000010000000000,
19 => 0b1110010000000000000,
20 => 0b10010000000000000000,
21 => 0b101000000000000000000,
22 => 0b1100000000000000000000,
23 => 0b10000100000000000000000,
24 => 0b111000010000000000000000, 25 => 0b1000100000000000000000000,
26 => 0b10010000000000000000000000,
27 => 0b101000000000000000000000000,
28 => 0b1011100000000000000000000000,
29 => 0b11000000000000000000000000000,
30 => 0b110010000000000000000000000000,
31 => 0b1101000000000000000000000000000,
32 => 0b11100000000000000000000000000000,
_ => 0b101101,
}
}