Skip to content

Commit 350ba17

Browse files
authored
Merge pull request #925 from dhardy/master
Bernoulli: catch other invalid parameterisations; fix doc links
2 parents 56f7625 + 61b8818 commit 350ba17

File tree

7 files changed

+29
-38
lines changed

7 files changed

+29
-38
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ A [separate changelog is kept for rand_core](rand_core/CHANGELOG.md).
99
You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.html) useful.
1010

1111
## Unreleased
12+
### Fixes
13+
- The `Bernoulli` distribution constructors now reports an error on NaN and on
14+
`denominator == 0`. (#925)
15+
1216
### Additions
1317
- Implement `std::error::Error` for `BernoulliError` (#919)
1418

rand_core/src/lib.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -141,24 +141,22 @@ pub trait RngCore {
141141
///
142142
/// RNGs must implement at least one method from this trait directly. In
143143
/// the case this method is not implemented directly, it can be implemented
144-
/// using `self.next_u64() as u32` or via
145-
/// [`fill_bytes`](impls::next_u32_via_fill).
144+
/// using `self.next_u64() as u32` or via [`impls::next_u32_via_fill`].
146145
fn next_u32(&mut self) -> u32;
147146

148147
/// Return the next random `u64`.
149148
///
150149
/// RNGs must implement at least one method from this trait directly. In
151150
/// the case this method is not implemented directly, it can be implemented
152-
/// via [`next_u32`](impls::next_u64_via_u32) or via
153-
/// [`fill_bytes`](impls::next_u64_via_fill).
151+
/// via [`impls::next_u64_via_u32`] or via [`impls::next_u64_via_fill`].
154152
fn next_u64(&mut self) -> u64;
155153

156154
/// Fill `dest` with random data.
157155
///
158156
/// RNGs must implement at least one method from this trait directly. In
159157
/// the case this method is not implemented directly, it can be implemented
160-
/// via [`next_u*`](impls::fill_bytes_via_next) or
161-
/// via [`try_fill_bytes`](RngCore::try_fill_bytes); if this generator can
158+
/// via [`impls::fill_bytes_via_next`] or
159+
/// via [`RngCore::try_fill_bytes`]; if this generator can
162160
/// fail the implementation must choose how best to handle errors here
163161
/// (e.g. panic with a descriptive message or log a warning and retry a few
164162
/// times).
@@ -176,12 +174,10 @@ pub trait RngCore {
176174
/// by external (true) RNGs (e.g. `OsRng`) which can fail. It may be used
177175
/// directly to generate keys and to seed (infallible) PRNGs.
178176
///
179-
/// Other than error handling, this method is identical to [`fill_bytes`];
177+
/// Other than error handling, this method is identical to [`RngCore::fill_bytes`];
180178
/// thus this may be implemented using `Ok(self.fill_bytes(dest))` or
181179
/// `fill_bytes` may be implemented with
182180
/// `self.try_fill_bytes(dest).unwrap()` or more specific error handling.
183-
///
184-
/// [`fill_bytes`]: RngCore::fill_bytes
185181
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>;
186182
}
187183

src/distributions/bernoulli.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl Bernoulli {
9393
/// 2<sup>-64</sup> in `[0, 1]` can be represented as a `f64`.)
9494
#[inline]
9595
pub fn new(p: f64) -> Result<Bernoulli, BernoulliError> {
96-
if p < 0.0 || p >= 1.0 {
96+
if !(p >= 0.0 && p < 1.0) {
9797
if p == 1.0 { return Ok(Bernoulli { p_int: ALWAYS_TRUE }) }
9898
return Err(BernoulliError::InvalidProbability);
9999
}
@@ -104,11 +104,13 @@ impl Bernoulli {
104104
/// `numerator`-in-`denominator`. I.e. `new_ratio(2, 3)` will return
105105
/// a `Bernoulli` with a 2-in-3 chance, or about 67%, of returning `true`.
106106
///
107-
/// If `numerator == denominator` then the returned `Bernoulli` will always
108107
/// return `true`. If `numerator == 0` it will always return `false`.
108+
/// For `numerator > denominator` and `denominator == 0`, this returns an
109+
/// error. Otherwise, for `numerator == denominator`, samples are always
110+
/// true; for `numerator == 0` samples are always false.
109111
#[inline]
110112
pub fn from_ratio(numerator: u32, denominator: u32) -> Result<Bernoulli, BernoulliError> {
111-
if numerator > denominator {
113+
if numerator > denominator || denominator == 0 {
112114
return Err(BernoulliError::InvalidProbability);
113115
}
114116
if numerator == denominator {

src/distributions/mod.rs

+4-12
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@
3131
//! # The `Standard` distribution
3232
//!
3333
//! The [`Standard`] distribution is important to mention. This is the
34-
//! distribution used by [`Rng::gen()`] and represents the "default" way to
34+
//! distribution used by [`Rng::gen`] and represents the "default" way to
3535
//! produce a random value for many different types, including most primitive
3636
//! types, tuples, arrays, and a few derived types. See the documentation of
3737
//! [`Standard`] for more details.
3838
//!
3939
//! Implementing `Distribution<T>` for [`Standard`] for user types `T` makes it
40-
//! possible to generate type `T` with [`Rng::gen()`], and by extension also
41-
//! with the [`random()`] function.
40+
//! possible to generate type `T` with [`Rng::gen`], and by extension also
41+
//! with the [`random`] function.
4242
//!
4343
//! ## Random characters
4444
//!
@@ -89,15 +89,7 @@
8989
//! [`rand_distr`]: https://crates.io/crates/rand_distr
9090
//! [`statrs`]: https://crates.io/crates/statrs
9191
92-
//! [`Alphanumeric`]: distributions::Alphanumeric
93-
//! [`Bernoulli`]: distributions::Bernoulli
94-
//! [`Open01`]: distributions::Open01
95-
//! [`OpenClosed01`]: distributions::OpenClosed01
96-
//! [`Standard`]: distributions::Standard
97-
//! [`Uniform`]: distributions::Uniform
98-
//! [`Uniform::new`]: distributions::Uniform::new
99-
//! [`Uniform::new_inclusive`]: distributions::Uniform::new_inclusive
100-
//! [`weighted`]: distributions::weighted
92+
//! [`random`]: crate::random
10193
//! [`rand_distr`]: https://crates.io/crates/rand_distr
10294
//! [`statrs`]: https://crates.io/crates/statrs
10395

src/rngs/mod.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,11 @@
8484
//! Some suggestions are: [`rand_chacha`], [`rand_pcg`], [`rand_xoshiro`].
8585
//! A full list can be found by searching for crates with the [`rng` tag].
8686
//!
87-
//! [`SmallRng`]: rngs::SmallRng
88-
//! [`StdRng`]: rngs::StdRng
89-
//! [`OsRng`]: rngs::OsRng
90-
//! [`ThreadRng`]: rngs::ThreadRng
91-
//! [`mock::StepRng`]: rngs::mock::StepRng
92-
//! [`adapter::ReadRng`]: rngs::adapter::ReadRng
93-
//! [`adapter::ReseedingRng`]: rngs::adapter::ReseedingRng
87+
//! [`Rng`]: crate::Rng
88+
//! [`RngCore`]: crate::RngCore
89+
//! [`CryptoRng`]: crate::CryptoRng
90+
//! [`SeedableRng`]: crate::SeedableRng
91+
//! [`thread_rng`]: crate::thread_rng
9492
//! [`rdrand`]: https://crates.io/crates/rdrand
9593
//! [`rand_jitter`]: https://crates.io/crates/rand_jitter
9694
//! [`rand_chacha`]: https://crates.io/crates/rand_chacha

src/rngs/std.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ pub(crate) use rand_chacha::ChaCha20Core as Core;
2222
/// on the current platform, to be statistically strong and unpredictable
2323
/// (meaning a cryptographically secure PRNG).
2424
///
25-
/// The current algorithm used is the ChaCha block cipher with either 20 or 12
26-
/// rounds (see the `stdrng_*` feature flags, documented in the README).
25+
/// The current algorithm used is the ChaCha block cipher with 20 rounds.
2726
/// This may change as new evidence of cipher security and performance
2827
/// becomes available.
2928
///

src/seq/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@
1010
//!
1111
//! This module provides:
1212
//!
13-
//! * [`seq::SliceRandom`] slice sampling and mutation
14-
//! * [`seq::IteratorRandom`] iterator sampling
15-
//! * [`seq::index::sample`] low-level API to choose multiple indices from
13+
//! * [`SliceRandom`] slice sampling and mutation
14+
//! * [`IteratorRandom`] iterator sampling
15+
//! * [`index::sample`] low-level API to choose multiple indices from
1616
//! `0..length`
1717
//!
1818
//! Also see:
1919
//!
20-
//! * [`distributions::weighted`] module which provides implementations of
21-
//! weighted index sampling.
20+
//! * [`crate::distributions::weighted`] module which provides
21+
//! implementations of weighted index sampling.
2222
//!
2323
//! In order to make results reproducible across 32-64 bit architectures, all
2424
//! `usize` indices are sampled as a `u32` where possible (also providing a

0 commit comments

Comments
 (0)