From 7473e4141d74f7e9d3c5e79c0afb83cc8773b333 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Sun, 31 Mar 2024 05:22:24 +0200 Subject: [PATCH] narcissus-core: Improve float random generation Change `next_f32` to output in the range `[0.0,1.0)`. Add `next_f64`. Add very basic smoke test. --- engine/narcissus-core/src/rand.rs | 34 ++++++++++++++++++++++++++++--- title/shark/src/main.rs | 2 +- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/engine/narcissus-core/src/rand.rs b/engine/narcissus-core/src/rand.rs index e46c206..1ad9147 100644 --- a/engine/narcissus-core/src/rand.rs +++ b/engine/narcissus-core/src/rand.rs @@ -62,16 +62,26 @@ impl Pcg64 { (result + carry as u64).widen() } - /// Generates a uniformly distributed random float in the range `-1.0..1.0` + /// Generates a uniformly distributed random f32 in the range `0.0..1.0` /// - /// Always draws two 64 bit words from the PRNG. + /// Always draws one 64 bit word from the PRNG. #[inline] #[must_use] pub fn next_f32(&mut self) -> f32 { - let value = (self.next_u64() >> (64 - 25)) as i64 as f32; + let value = (self.next_u64() >> (64 - 24)) as i64 as f32; value * 5.960_464_5e-8 // 0x1p-24f } + /// Generates a uniformly distributed random f64 in the range `0.0..1.0` + /// + /// Always draws one 64 bit word from the PRNG. + #[inline] + #[must_use] + pub fn next_f64(&mut self) -> f64 { + let value = (self.next_u64() >> (64 - 53)) as i64 as f64; + value * 1.110_223_024_625_156_5e-16 // 0x1p-53 + } + /// Randomly select an an element from `slice` with uniform probability. /// /// Always draws two 64 bit words from the PRNG. @@ -219,4 +229,22 @@ mod tests { let mut rng = Pcg64::new(); assert_eq!(rng.select(slice), None); } + + #[test] + fn uniform_f32() { + let mut rng = Pcg64::new(); + for _ in 0..100_000 { + let x = rng.next_f32(); + assert!(x >= 0.0 && x < 1.0); + } + } + + #[test] + fn uniform_f64() { + let mut rng = Pcg64::new(); + for _ in 0..100_000 { + let x = rng.next_f64(); + assert!(x >= 0.0 && x < 1.0); + } + } } diff --git a/title/shark/src/main.rs b/title/shark/src/main.rs index 271c7eb..1bed121 100644 --- a/title/shark/src/main.rs +++ b/title/shark/src/main.rs @@ -188,7 +188,7 @@ pub fn main() { let x = x as f32 * shark_distance - NUM_SHARKS as f32 / 2.0 * shark_distance; let z = z as f32 * shark_distance - NUM_SHARKS as f32 / 2.0 * shark_distance; shark_transforms.push(Affine3 { - matrix: Mat3::from_axis_rotation(Vec3::Y, HalfTurn::new(rng.next_f32())), + matrix: Mat3::from_axis_rotation(Vec3::Y, HalfTurn::new(rng.next_f32() * 2.0)), translate: vec3(x, 0.0, z), }) } -- 2.49.0