pub(crate) fn rand_f64() -> f64 {
use std::cell::Cell;
use std::time::{SystemTime, UNIX_EPOCH};
thread_local! {
static COUNTER: Cell<u64> = const { Cell::new(1) };
}
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_nanos() as u64)
.unwrap_or(1);
let state = COUNTER.with(|c| {
let next = c.get().wrapping_add(1);
c.set(next);
next
});
let mut x = nanos ^ state.wrapping_mul(0x9e3779b97f4a7c15);
x ^= x >> 30;
x = x.wrapping_mul(0xbf58476d1ce4e5b9);
x ^= x >> 27;
x = x.wrapping_mul(0x94d049bb133111eb);
x ^= x >> 31;
(x >> 11) as f64 / (1u64 << 53) as f64
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rand_f64_in_range() {
for _ in 0..1000 {
let r = rand_f64();
assert!((0.0..1.0).contains(&r), "rand_f64() returned {}", r);
}
}
}