Skip to main content

iris/core/
rng.rs

1/// A pure Rust pseudo-random number generator implementing Xorshift128+.
2/// This provides standard random number generation functionality without external dependencies.
3#[derive(Clone, Debug)]
4pub struct Rng {
5    state: [u64; 2],
6}
7
8impl Rng {
9    /// Creates a new RNG with a given seed.
10    #[must_use]
11    pub fn new(seed: u64) -> Self {
12        let mut rng = Self {
13            state: [seed, seed ^ 0x72636467_75736867],
14        };
15        // Warm up the generator
16        for _ in 0..10 {
17            rng.next_u64();
18        }
19        rng
20    }
21
22    /// Generates the next random 64-bit unsigned integer.
23    pub fn next_u64(&mut self) -> u64 {
24        let mut s1 = self.state[0];
25        let s0 = self.state[1];
26        let result = s1.wrapping_add(s0);
27        self.state[0] = s0;
28        s1 ^= s1 << 23; // a
29        self.state[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5); // b, c
30        result
31    }
32
33    /// Generates the next random 32-bit unsigned integer.
34    pub fn next_u32(&mut self) -> u32 {
35        (self.next_u64() >> 32) as u32
36    }
37
38    /// Generates the next random 32-bit float in the range [0.0, 1.0).
39    pub fn next_f32(&mut self) -> f32 {
40        let val = self.next_u32();
41        (val as f32) / (u32::MAX as f32)
42    }
43
44    /// Generates the next random 64-bit float in the range [0.0, 1.0).
45    pub fn next_f64(&mut self) -> f64 {
46        let val = self.next_u64();
47        (val as f64) / (u64::MAX as f64)
48    }
49}
50
51impl Default for Rng {
52    fn default() -> Self {
53        Self::new(123456789)
54    }
55}