Skip to content

Commit

Permalink
Merge pull request #925 from dhardy/master
Browse files Browse the repository at this point in the history
Bernoulli: catch other invalid parameterisations; fix doc links
  • Loading branch information
dhardy committed Jan 2, 2020
2 parents 56f7625 + 61b8818 commit 350ba17
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 38 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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)

Expand Down
14 changes: 5 additions & 9 deletions rand_core/src/lib.rs
Expand Up @@ -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).
Expand All @@ -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>;
}

Expand Down
8 changes: 5 additions & 3 deletions src/distributions/bernoulli.rs
Expand Up @@ -93,7 +93,7 @@ impl Bernoulli {
/// 2<sup>-64</sup> in `[0, 1]` can be represented as a `f64`.)
#[inline]
pub fn new(p: f64) -> Result<Bernoulli, BernoulliError> {
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);
}
Expand All @@ -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<Bernoulli, BernoulliError> {
if numerator > denominator {
if numerator > denominator || denominator == 0 {
return Err(BernoulliError::InvalidProbability);
}
if numerator == denominator {
Expand Down
16 changes: 4 additions & 12 deletions src/distributions/mod.rs
Expand Up @@ -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<T>` 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
//!
Expand Down Expand Up @@ -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

Expand Down
12 changes: 5 additions & 7 deletions src/rngs/mod.rs
Expand Up @@ -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
Expand Down
3 changes: 1 addition & 2 deletions src/rngs/std.rs
Expand Up @@ -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.
///
Expand Down
10 changes: 5 additions & 5 deletions src/seq/mod.rs
Expand Up @@ -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
Expand Down

0 comments on commit 350ba17

Please sign in to comment.