const TWO_M53: f64 = 1.0 / (1u64 << 53) as f64;
const TWO_M24: f32 = 1.0 / (1u32 << 24) as f32;
#[inline]
pub fn f64_53bits(mut bits: impl FnMut() -> u64) -> f64 {
(bits() >> 11) as f64 * TWO_M53
}
#[inline]
pub fn f32_24bits(mut bits: impl FnMut() -> u64) -> f32 {
(bits() >> 40) as f32 * TWO_M24
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sources::Weyl;
#[test]
fn test_range_and_distribution() {
let mut rng = Weyl(42);
for _ in 0..100_000 {
let x = f64_53bits(|| rng.next_u64());
assert!((0.0..1.0).contains(&x), "f64_53bits: {x}");
assert_eq!(x, (x / TWO_M53).round() * TWO_M53);
let y = f32_24bits(|| rng.next_u64());
assert!((0.0..1.0).contains(&y), "f32_24bits: {y}");
assert_eq!(y, (y / TWO_M24).round() * TWO_M24);
}
}
#[test]
fn test_extremes() {
assert_eq!(f64_53bits(|| 0), 0.0);
assert_eq!(f64_53bits(|| !0u64), 1.0 - TWO_M53);
assert_eq!(f32_24bits(|| 0), 0.0);
assert_eq!(f32_24bits(|| !0u64), 1.0 - TWO_M24);
}
}