#[derive(Debug, Clone)]
pub struct Rng {
state: u64,
}
impl Rng {
pub fn seeded(seed: u64) -> Self {
Self { state: seed }
}
#[inline]
pub fn next_u64(&mut self) -> u64 {
self.state = self.state.wrapping_add(0x9e3779b97f4a7c15);
let mut z = self.state;
z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb);
z ^ (z >> 31)
}
#[inline]
pub fn next_f64(&mut self) -> f64 {
(self.next_u64() >> 11) as f64 / (1u64 << 53) as f64
}
pub fn next_normal(&mut self) -> f64 {
let u1 = self.next_f64().max(f64::MIN_POSITIVE); let u2 = self.next_f64();
(-2.0 * u1.ln()).sqrt() * (2.0 * std::f64::consts::PI * u2).cos()
}
pub fn fork(&mut self) -> Rng {
Rng::seeded(self.next_u64())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_determinism() {
let mut a = Rng::seeded(42);
let mut b = Rng::seeded(42);
for _ in 0..100 {
assert_eq!(a.next_u64(), b.next_u64());
}
}
#[test]
fn test_f64_range() {
let mut rng = Rng::seeded(123);
for _ in 0..1000 {
let v = rng.next_f64();
assert!(v >= 0.0 && v < 1.0);
}
}
#[test]
fn test_fork_independence() {
let mut rng = Rng::seeded(42);
let mut child = rng.fork();
assert_ne!(rng.next_u64(), child.next_u64());
}
}