Prevent random floats from occasionally being greater than 1.

Previously, gen_f64 could generate numbers as high as 1.0000000002328306
in the case that u3 was 4294967295.0f64 and u2 was nonzero.  This change
divides the random numbers by 2**32 instead, effectively concatenating
their bits as apparently intended.  (Bonus fix: const.)

The comments are updated to be more specific than "random float"; note
that this can still generate 1.0f64 (P = 2**-54) due to rounding.
This commit is contained in:
Jed Davis
2012-07-16 19:28:32 -07:00
parent 0e42004bab
commit db34b5acd1

View File

@@ -94,22 +94,22 @@ impl extensions for rng {
(self.next() as u64 << 32) | self.next() as u64 (self.next() as u64 << 32) | self.next() as u64
} }
/// Return a random float /// Return a random float in the interval [0,1]
fn gen_float() -> float { fn gen_float() -> float {
self.gen_f64() as float self.gen_f64() as float
} }
/// Return a random f32 /// Return a random f32 in the interval [0,1]
fn gen_f32() -> f32 { fn gen_f32() -> f32 {
self.gen_f64() as f32 self.gen_f64() as f32
} }
/// Return a random f64 /// Return a random f64 in the interval [0,1]
fn gen_f64() -> f64 { fn gen_f64() -> f64 {
let u1 = self.next() as f64; let u1 = self.next() as f64;
let u2 = self.next() as f64; let u2 = self.next() as f64;
let u3 = self.next() as f64; let u3 = self.next() as f64;
let scale = u32::max_value as f64; const scale : f64 = (u32::max_value as f64) + 1.0f64;
ret ((u1 / scale + u2) / scale + u3) / scale; ret ((u1 / scale + u2) / scale + u3) / scale;
} }