tb/
rng.rs

1
2//! A small random number generator.
3//! Warning: Not cryptographically secure.
4
5pub trait Rand {
6    fn new(seed: u64) -> Self;
7    fn rand_u32(&mut self) -> u32;
8
9    fn rand_u8(&mut self) -> u8 {
10        return self.rand_u32() as u8;
11    }
12    fn rand_u16(&mut self) -> u16 {
13        return self.rand_u32() as u16;
14    }
15    fn rand_u64(&mut self) -> u64 {
16        return (self.rand_u32() as u64)<<32 | (self.rand_u32() as u64);
17    }
18
19    #[cfg(target_pointer_width = "32")]
20    fn rand_usize(&mut self) -> usize {
21        return self.rand_u32() as usize;
22    }
23
24    #[cfg(target_pointer_width = "64")]
25    fn rand_usize(&mut self) -> usize {
26        return self.rand_u64() as usize;
27    }
28    
29    fn rand_bounded_u32(&mut self, m: u32) -> u32 {
30        let threshold = m.wrapping_neg().wrapping_rem(m);
31        loop {
32            let r = self.rand_u32();
33            if r >= threshold {
34                return r.wrapping_rem(m);
35            }
36        }
37    }
38    fn rand_bounded_u64(&mut self, m: u64) -> u64 {
39        let threshold = m.wrapping_neg().wrapping_rem(m);
40        loop {
41            let r = self.rand_u64();
42            if r >= threshold {
43                return r.wrapping_rem(m);
44            }
45        }
46    }
47
48    #[cfg(target_pointer_width = "32")]
49    fn rand_bounded_usize(&mut self, m: usize) -> usize{
50        return self.rand_bounded_u32(m as u32) as usize;
51    }
52
53    #[cfg(target_pointer_width = "64")]
54    fn rand_bounded_usize(&mut self, m: usize) -> usize{
55        return self.rand_bounded_u64(m as u64) as usize;
56    }
57
58    fn rand_range_u32(&mut self, a: u32, b: u32) -> u32 {
59       return a+self.rand_bounded_u32(b-a);
60    }
61    fn rand_range_u64(&mut self, a: u64, b: u64) -> u64 {
62       return a+self.rand_bounded_u64(b-a);
63    }
64    fn rand_range_i32(&mut self, a: i32, b: i32) -> i32 {
65        return a+self.rand_bounded_u32((b-a) as u32) as i32;
66    }
67    fn rand_range_i64(&mut self, a: i64, b: i64) -> i64 {
68        return a+self.rand_bounded_u64((b-a) as u64) as i64;
69    }
70
71    fn rand_f32(&mut self) -> f32 {
72        return self.rand_u32() as f32 * 2.3283064365386963E-10;
73    }
74    fn rand_f64(&mut self) -> f64 {
75        return self.rand_u32() as f64 * 2.3283064365386963E-10;
76    }
77
78    fn shuffle<T>(&mut self, a: &mut [T]) {
79        if a.len()==0 {return;}
80        let mut i = a.len()-1;
81        while i>0 {
82            let j = (self.rand_u32() as usize)%(i+1);
83            a.swap(i,j);
84            i-=1;
85        }
86    }
87}
88
89// PCG-XSH-RR
90pub struct Rng {
91    state: u64
92}
93impl Rng {
94    fn rand(&mut self) -> u32 {
95        const MULTIPLIER: u64 = 6364136223846793005;
96        const INC: u64 = 1442695040888963407;
97        let oldstate = self.state;
98        self.state = oldstate.wrapping_mul(MULTIPLIER).wrapping_add(INC|1);
99        let xorshifted: u32 = ((
100            (oldstate.wrapping_shr(18)) ^ oldstate
101        ).wrapping_shr(27)) as u32;
102        let rot: u32 = (oldstate.wrapping_shr(59)) as u32;
103        return (xorshifted.wrapping_shr(rot)) | (
104            xorshifted.wrapping_shl(rot.wrapping_neg() & 31)
105        );
106    }
107}
108impl Rand for Rng {
109    fn new(seed: u64) -> Self {
110        let mut rng = Self{state: 0};
111        rng.rand();
112        rng.state = rng.state.wrapping_add(seed);
113        rng.rand();
114        return rng;
115    }
116    fn rand_u32(&mut self) -> u32 {
117        return self.rand();
118    }
119}