diff --git a/CHANGELOG.md b/CHANGELOG.md index 95b4022ec9d..57bb3614ff8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ A [separate changelog is kept for rand_core](rand_core/CHANGELOG.md). You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.html) useful. ## Unreleased +### Fixes +- The `Bernoulli` distribution constructors now reports an error on NaN and on + `denominator == 0`. (#925) + ### Additions - Implement `std::error::Error` for `BernoulliError` (#919) diff --git a/rand_core/src/lib.rs b/rand_core/src/lib.rs index 6e91c3c576f..f0a9f9431e3 100644 --- a/rand_core/src/lib.rs +++ b/rand_core/src/lib.rs @@ -141,24 +141,22 @@ pub trait RngCore { /// /// RNGs must implement at least one method from this trait directly. In /// the case this method is not implemented directly, it can be implemented - /// using `self.next_u64() as u32` or via - /// [`fill_bytes`](impls::next_u32_via_fill). + /// using `self.next_u64() as u32` or via [`impls::next_u32_via_fill`]. fn next_u32(&mut self) -> u32; /// Return the next random `u64`. /// /// RNGs must implement at least one method from this trait directly. In /// the case this method is not implemented directly, it can be implemented - /// via [`next_u32`](impls::next_u64_via_u32) or via - /// [`fill_bytes`](impls::next_u64_via_fill). + /// via [`impls::next_u64_via_u32`] or via [`impls::next_u64_via_fill`]. fn next_u64(&mut self) -> u64; /// Fill `dest` with random data. /// /// RNGs must implement at least one method from this trait directly. In /// the case this method is not implemented directly, it can be implemented - /// via [`next_u*`](impls::fill_bytes_via_next) or - /// via [`try_fill_bytes`](RngCore::try_fill_bytes); if this generator can + /// via [`impls::fill_bytes_via_next`] or + /// via [`RngCore::try_fill_bytes`]; if this generator can /// fail the implementation must choose how best to handle errors here /// (e.g. panic with a descriptive message or log a warning and retry a few /// times). @@ -176,12 +174,10 @@ pub trait RngCore { /// by external (true) RNGs (e.g. `OsRng`) which can fail. It may be used /// directly to generate keys and to seed (infallible) PRNGs. /// - /// Other than error handling, this method is identical to [`fill_bytes`]; + /// Other than error handling, this method is identical to [`RngCore::fill_bytes`]; /// thus this may be implemented using `Ok(self.fill_bytes(dest))` or /// `fill_bytes` may be implemented with /// `self.try_fill_bytes(dest).unwrap()` or more specific error handling. - /// - /// [`fill_bytes`]: RngCore::fill_bytes fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>; } diff --git a/src/distributions/bernoulli.rs b/src/distributions/bernoulli.rs index e8099606e65..024233a53b2 100644 --- a/src/distributions/bernoulli.rs +++ b/src/distributions/bernoulli.rs @@ -93,7 +93,7 @@ impl Bernoulli { /// 2-64 in `[0, 1]` can be represented as a `f64`.) #[inline] pub fn new(p: f64) -> Result { - if p < 0.0 || p >= 1.0 { + if !(p >= 0.0 && p < 1.0) { if p == 1.0 { return Ok(Bernoulli { p_int: ALWAYS_TRUE }) } return Err(BernoulliError::InvalidProbability); } @@ -104,11 +104,13 @@ impl Bernoulli { /// `numerator`-in-`denominator`. I.e. `new_ratio(2, 3)` will return /// a `Bernoulli` with a 2-in-3 chance, or about 67%, of returning `true`. /// - /// If `numerator == denominator` then the returned `Bernoulli` will always /// return `true`. If `numerator == 0` it will always return `false`. + /// For `numerator > denominator` and `denominator == 0`, this returns an + /// error. Otherwise, for `numerator == denominator`, samples are always + /// true; for `numerator == 0` samples are always false. #[inline] pub fn from_ratio(numerator: u32, denominator: u32) -> Result { - if numerator > denominator { + if numerator > denominator || denominator == 0 { return Err(BernoulliError::InvalidProbability); } if numerator == denominator { diff --git a/src/distributions/mod.rs b/src/distributions/mod.rs index 5091d3ba8ab..7a1e7629aa0 100644 --- a/src/distributions/mod.rs +++ b/src/distributions/mod.rs @@ -31,14 +31,14 @@ //! # The `Standard` distribution //! //! The [`Standard`] distribution is important to mention. This is the -//! distribution used by [`Rng::gen()`] and represents the "default" way to +//! distribution used by [`Rng::gen`] and represents the "default" way to //! produce a random value for many different types, including most primitive //! types, tuples, arrays, and a few derived types. See the documentation of //! [`Standard`] for more details. //! //! Implementing `Distribution` for [`Standard`] for user types `T` makes it -//! possible to generate type `T` with [`Rng::gen()`], and by extension also -//! with the [`random()`] function. +//! possible to generate type `T` with [`Rng::gen`], and by extension also +//! with the [`random`] function. //! //! ## Random characters //! @@ -89,15 +89,7 @@ //! [`rand_distr`]: https://crates.io/crates/rand_distr //! [`statrs`]: https://crates.io/crates/statrs -//! [`Alphanumeric`]: distributions::Alphanumeric -//! [`Bernoulli`]: distributions::Bernoulli -//! [`Open01`]: distributions::Open01 -//! [`OpenClosed01`]: distributions::OpenClosed01 -//! [`Standard`]: distributions::Standard -//! [`Uniform`]: distributions::Uniform -//! [`Uniform::new`]: distributions::Uniform::new -//! [`Uniform::new_inclusive`]: distributions::Uniform::new_inclusive -//! [`weighted`]: distributions::weighted +//! [`random`]: crate::random //! [`rand_distr`]: https://crates.io/crates/rand_distr //! [`statrs`]: https://crates.io/crates/statrs diff --git a/src/rngs/mod.rs b/src/rngs/mod.rs index abf3243c10f..1d9f5185d6e 100644 --- a/src/rngs/mod.rs +++ b/src/rngs/mod.rs @@ -84,13 +84,11 @@ //! Some suggestions are: [`rand_chacha`], [`rand_pcg`], [`rand_xoshiro`]. //! A full list can be found by searching for crates with the [`rng` tag]. //! -//! [`SmallRng`]: rngs::SmallRng -//! [`StdRng`]: rngs::StdRng -//! [`OsRng`]: rngs::OsRng -//! [`ThreadRng`]: rngs::ThreadRng -//! [`mock::StepRng`]: rngs::mock::StepRng -//! [`adapter::ReadRng`]: rngs::adapter::ReadRng -//! [`adapter::ReseedingRng`]: rngs::adapter::ReseedingRng +//! [`Rng`]: crate::Rng +//! [`RngCore`]: crate::RngCore +//! [`CryptoRng`]: crate::CryptoRng +//! [`SeedableRng`]: crate::SeedableRng +//! [`thread_rng`]: crate::thread_rng //! [`rdrand`]: https://crates.io/crates/rdrand //! [`rand_jitter`]: https://crates.io/crates/rand_jitter //! [`rand_chacha`]: https://crates.io/crates/rand_chacha diff --git a/src/rngs/std.rs b/src/rngs/std.rs index 8ebe6b8ec1f..6d02c2d3891 100644 --- a/src/rngs/std.rs +++ b/src/rngs/std.rs @@ -22,8 +22,7 @@ pub(crate) use rand_chacha::ChaCha20Core as Core; /// on the current platform, to be statistically strong and unpredictable /// (meaning a cryptographically secure PRNG). /// -/// The current algorithm used is the ChaCha block cipher with either 20 or 12 -/// rounds (see the `stdrng_*` feature flags, documented in the README). +/// The current algorithm used is the ChaCha block cipher with 20 rounds. /// This may change as new evidence of cipher security and performance /// becomes available. /// diff --git a/src/seq/mod.rs b/src/seq/mod.rs index ea28ce33511..91f6c2808f1 100644 --- a/src/seq/mod.rs +++ b/src/seq/mod.rs @@ -10,15 +10,15 @@ //! //! This module provides: //! -//! * [`seq::SliceRandom`] slice sampling and mutation -//! * [`seq::IteratorRandom`] iterator sampling -//! * [`seq::index::sample`] low-level API to choose multiple indices from +//! * [`SliceRandom`] slice sampling and mutation +//! * [`IteratorRandom`] iterator sampling +//! * [`index::sample`] low-level API to choose multiple indices from //! `0..length` //! //! Also see: //! -//! * [`distributions::weighted`] module which provides implementations of -//! weighted index sampling. +//! * [`crate::distributions::weighted`] module which provides +//! implementations of weighted index sampling. //! //! In order to make results reproducible across 32-64 bit architectures, all //! `usize` indices are sampled as a `u32` where possible (also providing a