stocking

git clone https://git.bradleygannon.com/stocking.git
Log | Files | Refs

random.rs (1394B)


      1 use std::time::SystemTime;
      2 
      3 #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)]
      4 pub struct RandomNumberGenerator {
      5     state: u64,
      6 }
      7 
      8 impl RandomNumberGenerator {
      9     const MULTIPLIER: u64 = 6364136223846793005;
     10     const INCREMENT: u64 = 1442695040888963407;
     11 
     12     pub fn new(seed: u64) -> Self {
     13         let mut rng = Self { state: 0 };
     14         let _ = rng.next_u32();
     15         let _ = rng.state.wrapping_add(seed);
     16         let _ = rng.next_u32();
     17         rng
     18     }
     19 
     20     pub fn new_with_time_seed() -> Self {
     21         let nanos = SystemTime::now()
     22             .duration_since(SystemTime::UNIX_EPOCH)
     23             .unwrap()
     24             .as_nanos();
     25         Self::new(nanos as u64)
     26     }
     27 
     28     fn next_u32(&mut self) -> u32 {
     29         let old = self.state;
     30         self.state = old
     31             .wrapping_mul(Self::MULTIPLIER)
     32             .wrapping_add(Self::INCREMENT);
     33 
     34         let xorshifted = (((old >> 18) ^ old) >> 27) as u32;
     35         let rot = (old >> 59) as u32;
     36         xorshifted.rotate_right(rot)
     37     }
     38 
     39     pub fn next_f64(&mut self) -> f64 {
     40         let high = self.next_u32() as u64;
     41         let low = self.next_u32() as u64;
     42         let bits64 = (high << 32) | low;
     43 
     44         let r = bits64 >> 11;
     45         (r as f64) * (1.0 / ((1u64 << 53) as f64))
     46     }
     47 
     48     pub fn next_f64_in_range(&mut self, min: f64, max: f64) -> f64 {
     49         min + (max - min) * self.next_f64()
     50     }
     51 }