Skip to main content

material_colors/utils/
random.rs

1/// Partial LCG Algorithm implementation.
2pub struct Random(i64);
3
4impl Random {
5    pub const fn new(seed: i64) -> Self {
6        Self((seed ^ 0x5DEECE66Di64) & ((1i64 << 48) - 1))
7    }
8
9    fn _next(&mut self, bits: i64) -> i32 {
10        self.0 = (self.0.wrapping_mul(0x5DEECE66Di64).wrapping_add(0xBi64)) & ((1i64 << 48) - 1);
11
12        ((self.0 as u64) >> (48 - bits)) as i32
13    }
14
15    pub fn next_range(&mut self, range: i32) -> i32 {
16        if (range & -range) == range {
17            return (i64::from(range).wrapping_mul(i64::from(self._next(31))) >> 31) as i32;
18        }
19
20        let mut bits: i32;
21        let mut val: i32;
22
23        loop {
24            bits = self._next(31);
25            val = bits % range;
26
27            if !bits - val + (range - 1) < 0 {
28                break;
29            }
30        }
31
32        val
33    }
34}