Skip to content

Commit 22b1f80

Browse files
committed
Document open interval
1 parent 4ec66fb commit 22b1f80

File tree

3 files changed

+23
-12
lines changed

3 files changed

+23
-12
lines changed

src/distributions/float.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,6 @@ macro_rules! float_impls {
4545
impl Distribution<$ty> for Uniform {
4646
/// Generate a floating point number in the open interval `(0, 1)`
4747
/// (not including either endpoint) with a uniform distribution.
48-
///
49-
/// # Example
50-
/// ```rust
51-
/// use rand::{NewRng, SmallRng, Rng};
52-
/// use rand::distributions::Uniform;
53-
///
54-
/// let val: f32 = SmallRng::new().sample(Uniform);
55-
/// println!("f32 from (0,1): {}", val);
56-
/// ```
5748
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {
5849
const EPSILON: $ty = 1.0 / (1u64 << $fraction_bits) as $ty;
5950
let float_size = mem::size_of::<$ty>() * 8;

src/distributions/mod.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl<'a, T, D: Distribution<T>> Distribution<T> for &'a D {
177177
/// use rand::distributions::Uniform;
178178
///
179179
/// let val: f32 = SmallRng::new().sample(Uniform);
180-
/// println!("f32 from [0,1): {}", val);
180+
/// println!("f32 from (0,1): {}", val);
181181
/// ```
182182
///
183183
/// With dynamic dispatch (type erasure of `Rng`):
@@ -189,9 +189,29 @@ impl<'a, T, D: Distribution<T>> Distribution<T> for &'a D {
189189
/// let mut rng = thread_rng();
190190
/// let mut erased_rng: &mut RngCore = &mut rng;
191191
/// let val: f32 = erased_rng.sample(Uniform);
192-
/// println!("f32 from [0,1): {}", val);
192+
/// println!("f32 from (0,1): {}", val);
193193
/// ```
194194
///
195+
/// # Open interval for floats
196+
/// In theory it is possible to choose between an open interval `(0, 1)`, and
197+
/// the half-open intervals `[0, 1)` and `(0, 1]`. All can give a distribution
198+
/// with perfectly uniform intervals. Many libraries in other programming
199+
/// languages default to the closed-open interval `[0, 1)`. We choose here to go
200+
/// with *open*, with the arguments:
201+
///
202+
/// - The chance to generate a specific value, like exactly 0.0, is *tiny*. No
203+
/// (or almost no) sensible code relies on an exact floating-point value to be
204+
/// generated with a very small chance (1 in ~8 million (2^23) for `f32`, and
205+
/// 1 in 2^52 for `f64`). What is relied on is having a uniform distribution
206+
/// and a mean of `0.5`.
207+
/// - Several common algorithms rely on never seeing the value `0.0` generated,
208+
/// i.e. they rely on an open interval. For example when the logarithm of the
209+
/// value is taken, or used as a devisor.
210+
///
211+
/// In other words, the guarantee some value *could* be generated is less useful
212+
/// than the guarantee some value (`0.0`) is never generated. That makes an open
213+
/// interval a nicer choice.
214+
///
195215
/// [`Exp1`]: struct.Exp1.html
196216
/// [`StandardNormal`]: struct.StandardNormal.html
197217
#[derive(Debug)]

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ pub trait Rng: RngCore {
410410

411411
/// Return a random value supporting the [`Uniform`] distribution.
412412
///
413-
/// [`Uniform`]: struct.Uniform.html
413+
/// [`Uniform`]: distributions/struct.Uniform.html
414414
///
415415
/// # Example
416416
///

0 commit comments

Comments
 (0)