Rng renames: gen_ → random_ (#1505)
This commit is contained in:
parent
9d57b87e27
commit
8225d948b1
@ -30,6 +30,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.
|
|||||||
- Rename `Rng::gen_iter` to `random_iter` (#1500)
|
- Rename `Rng::gen_iter` to `random_iter` (#1500)
|
||||||
- Rename `rand::thread_rng()` to `rand::rng()`, and remove from the prelude (#1506)
|
- Rename `rand::thread_rng()` to `rand::rng()`, and remove from the prelude (#1506)
|
||||||
- Remove `rand::random()` from the prelude (#1506)
|
- Remove `rand::random()` from the prelude (#1506)
|
||||||
|
- Rename `Rng::gen_range` to `random_range`, `gen_bool` to `random_bool`, `gen_ratio` to `random_ratio` (#1505)
|
||||||
|
|
||||||
## [0.9.0-alpha.1] - 2024-03-18
|
## [0.9.0-alpha.1] - 2024-03-18
|
||||||
- Add the `Slice::num_choices` method to the Slice distribution (#1402)
|
- Add the `Slice::num_choices` method to the Slice distribution (#1402)
|
||||||
|
@ -21,7 +21,7 @@ criterion_group!(
|
|||||||
criterion_main!(benches);
|
criterion_main!(benches);
|
||||||
|
|
||||||
pub fn bench(c: &mut Criterion) {
|
pub fn bench(c: &mut Criterion) {
|
||||||
let mut g = c.benchmark_group("gen_1kb");
|
let mut g = c.benchmark_group("random_1kb");
|
||||||
g.throughput(criterion::Throughput::Bytes(1024));
|
g.throughput(criterion::Throughput::Bytes(1024));
|
||||||
|
|
||||||
g.bench_function("u16_iter_repeat", |b| {
|
g.bench_function("u16_iter_repeat", |b| {
|
||||||
|
@ -21,7 +21,7 @@ criterion_group!(
|
|||||||
criterion_main!(benches);
|
criterion_main!(benches);
|
||||||
|
|
||||||
pub fn bench(c: &mut Criterion) {
|
pub fn bench(c: &mut Criterion) {
|
||||||
let mut g = c.benchmark_group("gen_bool");
|
let mut g = c.benchmark_group("random_bool");
|
||||||
g.sample_size(1000);
|
g.sample_size(1000);
|
||||||
g.warm_up_time(core::time::Duration::from_millis(500));
|
g.warm_up_time(core::time::Duration::from_millis(500));
|
||||||
g.measurement_time(core::time::Duration::from_millis(1000));
|
g.measurement_time(core::time::Duration::from_millis(1000));
|
||||||
@ -33,25 +33,25 @@ pub fn bench(c: &mut Criterion) {
|
|||||||
|
|
||||||
g.bench_function("const", |b| {
|
g.bench_function("const", |b| {
|
||||||
let mut rng = Pcg32::from_rng(&mut rand::rng());
|
let mut rng = Pcg32::from_rng(&mut rand::rng());
|
||||||
b.iter(|| rng.gen_bool(0.18))
|
b.iter(|| rng.random_bool(0.18))
|
||||||
});
|
});
|
||||||
|
|
||||||
g.bench_function("var", |b| {
|
g.bench_function("var", |b| {
|
||||||
let mut rng = Pcg32::from_rng(&mut rand::rng());
|
let mut rng = Pcg32::from_rng(&mut rand::rng());
|
||||||
let p = rng.random();
|
let p = rng.random();
|
||||||
b.iter(|| rng.gen_bool(p))
|
b.iter(|| rng.random_bool(p))
|
||||||
});
|
});
|
||||||
|
|
||||||
g.bench_function("ratio_const", |b| {
|
g.bench_function("ratio_const", |b| {
|
||||||
let mut rng = Pcg32::from_rng(&mut rand::rng());
|
let mut rng = Pcg32::from_rng(&mut rand::rng());
|
||||||
b.iter(|| rng.gen_ratio(2, 3))
|
b.iter(|| rng.random_ratio(2, 3))
|
||||||
});
|
});
|
||||||
|
|
||||||
g.bench_function("ratio_var", |b| {
|
g.bench_function("ratio_var", |b| {
|
||||||
let mut rng = Pcg32::from_rng(&mut rand::rng());
|
let mut rng = Pcg32::from_rng(&mut rand::rng());
|
||||||
let d = rng.gen_range(1..=100);
|
let d = rng.random_range(1..=100);
|
||||||
let n = rng.gen_range(0..=d);
|
let n = rng.random_range(0..=d);
|
||||||
b.iter(|| rng.gen_ratio(n, d));
|
b.iter(|| rng.random_ratio(n, d));
|
||||||
});
|
});
|
||||||
|
|
||||||
g.bench_function("bernoulli_const", |b| {
|
g.bench_function("bernoulli_const", |b| {
|
||||||
|
@ -19,12 +19,12 @@ use rand_pcg::{Pcg32, Pcg64, Pcg64Dxsm, Pcg64Mcg};
|
|||||||
criterion_group!(
|
criterion_group!(
|
||||||
name = benches;
|
name = benches;
|
||||||
config = Criterion::default();
|
config = Criterion::default();
|
||||||
targets = gen_bytes, gen_u32, gen_u64, init_gen, init_from_u64, init_from_seed, reseeding_bytes
|
targets = random_bytes, random_u32, random_u64, init_gen, init_from_u64, init_from_seed, reseeding_bytes
|
||||||
);
|
);
|
||||||
criterion_main!(benches);
|
criterion_main!(benches);
|
||||||
|
|
||||||
pub fn gen_bytes(c: &mut Criterion) {
|
pub fn random_bytes(c: &mut Criterion) {
|
||||||
let mut g = c.benchmark_group("gen_bytes");
|
let mut g = c.benchmark_group("random_bytes");
|
||||||
g.warm_up_time(Duration::from_millis(500));
|
g.warm_up_time(Duration::from_millis(500));
|
||||||
g.measurement_time(Duration::from_millis(1000));
|
g.measurement_time(Duration::from_millis(1000));
|
||||||
g.throughput(criterion::Throughput::Bytes(1024));
|
g.throughput(criterion::Throughput::Bytes(1024));
|
||||||
@ -55,8 +55,8 @@ pub fn gen_bytes(c: &mut Criterion) {
|
|||||||
g.finish()
|
g.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_u32(c: &mut Criterion) {
|
pub fn random_u32(c: &mut Criterion) {
|
||||||
let mut g = c.benchmark_group("gen_u32");
|
let mut g = c.benchmark_group("random_u32");
|
||||||
g.sample_size(1000);
|
g.sample_size(1000);
|
||||||
g.warm_up_time(Duration::from_millis(500));
|
g.warm_up_time(Duration::from_millis(500));
|
||||||
g.measurement_time(Duration::from_millis(1000));
|
g.measurement_time(Duration::from_millis(1000));
|
||||||
@ -84,8 +84,8 @@ pub fn gen_u32(c: &mut Criterion) {
|
|||||||
g.finish()
|
g.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_u64(c: &mut Criterion) {
|
pub fn random_u64(c: &mut Criterion) {
|
||||||
let mut g = c.benchmark_group("gen_u64");
|
let mut g = c.benchmark_group("random_u64");
|
||||||
g.sample_size(1000);
|
g.sample_size(1000);
|
||||||
g.warm_up_time(Duration::from_millis(500));
|
g.warm_up_time(Duration::from_millis(500));
|
||||||
g.measurement_time(Duration::from_millis(1000));
|
g.measurement_time(Duration::from_millis(1000));
|
||||||
|
@ -251,7 +251,7 @@ impl<W: Clone + PartialEq + PartialOrd + SampleUniform + SubAssign<W> + Weight>
|
|||||||
if total_weight == W::ZERO {
|
if total_weight == W::ZERO {
|
||||||
return Err(WeightError::InsufficientNonZero);
|
return Err(WeightError::InsufficientNonZero);
|
||||||
}
|
}
|
||||||
let mut target_weight = rng.gen_range(W::ZERO..total_weight);
|
let mut target_weight = rng.random_range(W::ZERO..total_weight);
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
loop {
|
loop {
|
||||||
// Maybe descend into the left sub tree.
|
// Maybe descend into the left sub tree.
|
||||||
|
@ -76,7 +76,7 @@
|
|||||||
//! # Non-uniform sampling
|
//! # Non-uniform sampling
|
||||||
//!
|
//!
|
||||||
//! Sampling a simple true/false outcome with a given probability has a name:
|
//! Sampling a simple true/false outcome with a given probability has a name:
|
||||||
//! the [`Bernoulli`] distribution (this is used by [`Rng::gen_bool`]).
|
//! the [`Bernoulli`] distribution (this is used by [`Rng::random_bool`]).
|
||||||
//!
|
//!
|
||||||
//! For weighted sampling from a sequence of discrete values, use the
|
//! For weighted sampling from a sequence of discrete values, use the
|
||||||
//! [`WeightedIndex`] distribution.
|
//! [`WeightedIndex`] distribution.
|
||||||
@ -204,7 +204,7 @@ use crate::Rng;
|
|||||||
/// multiplicative method: `(rng.gen::<$uty>() >> N) as $ty * (ε/2)`.
|
/// multiplicative method: `(rng.gen::<$uty>() >> N) as $ty * (ε/2)`.
|
||||||
///
|
///
|
||||||
/// See also: [`Open01`] which samples from `(0, 1)`, [`OpenClosed01`] which
|
/// See also: [`Open01`] which samples from `(0, 1)`, [`OpenClosed01`] which
|
||||||
/// samples from `(0, 1]` and `Rng::gen_range(0..1)` which also samples from
|
/// samples from `(0, 1]` and `Rng::random_range(0..1)` which also samples from
|
||||||
/// `[0, 1)`. Note that `Open01` uses transmute-based methods which yield 1 bit
|
/// `[0, 1)`. Note that `Open01` uses transmute-based methods which yield 1 bit
|
||||||
/// less precision but may perform faster on some architectures (on modern Intel
|
/// less precision but may perform faster on some architectures (on modern Intel
|
||||||
/// CPUs all methods have approximately equal performance).
|
/// CPUs all methods have approximately equal performance).
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
//!
|
//!
|
||||||
//! [`Uniform`] is the standard distribution to sample uniformly from a range;
|
//! [`Uniform`] is the standard distribution to sample uniformly from a range;
|
||||||
//! e.g. `Uniform::new_inclusive(1, 6).unwrap()` can sample integers from 1 to 6, like a
|
//! e.g. `Uniform::new_inclusive(1, 6).unwrap()` can sample integers from 1 to 6, like a
|
||||||
//! standard die. [`Rng::gen_range`] supports any type supported by [`Uniform`].
|
//! standard die. [`Rng::random_range`] supports any type supported by [`Uniform`].
|
||||||
//!
|
//!
|
||||||
//! This distribution is provided with support for several primitive types
|
//! This distribution is provided with support for several primitive types
|
||||||
//! (all integer and floating-point types) as well as [`std::time::Duration`],
|
//! (all integer and floating-point types) as well as [`std::time::Duration`],
|
||||||
@ -33,7 +33,7 @@
|
|||||||
//! let side = Uniform::new(-10.0, 10.0).unwrap();
|
//! let side = Uniform::new(-10.0, 10.0).unwrap();
|
||||||
//!
|
//!
|
||||||
//! // sample between 1 and 10 points
|
//! // sample between 1 and 10 points
|
||||||
//! for _ in 0..rng.gen_range(1..=10) {
|
//! for _ in 0..rng.random_range(1..=10) {
|
||||||
//! // sample a point from the square with sides -10 - 10 in two dimensions
|
//! // sample a point from the square with sides -10 - 10 in two dimensions
|
||||||
//! let (x, y) = (rng.sample(side), rng.sample(side));
|
//! let (x, y) = (rng.sample(side), rng.sample(side));
|
||||||
//! println!("Point: {}, {}", x, y);
|
//! println!("Point: {}, {}", x, y);
|
||||||
@ -154,7 +154,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
/// [`Uniform::new`] and [`Uniform::new_inclusive`] construct a uniform
|
/// [`Uniform::new`] and [`Uniform::new_inclusive`] construct a uniform
|
||||||
/// distribution sampling from the given range; these functions may do extra
|
/// distribution sampling from the given range; these functions may do extra
|
||||||
/// work up front to make sampling of multiple values faster. If only one sample
|
/// work up front to make sampling of multiple values faster. If only one sample
|
||||||
/// from the range is required, [`Rng::gen_range`] can be more efficient.
|
/// from the range is required, [`Rng::random_range`] can be more efficient.
|
||||||
///
|
///
|
||||||
/// When sampling from a constant range, many calculations can happen at
|
/// When sampling from a constant range, many calculations can happen at
|
||||||
/// compile-time and all methods should be fast; for floating-point ranges and
|
/// compile-time and all methods should be fast; for floating-point ranges and
|
||||||
@ -186,18 +186,18 @@ use serde::{Deserialize, Serialize};
|
|||||||
/// println!("{}", sum);
|
/// println!("{}", sum);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// For a single sample, [`Rng::gen_range`] may be preferred:
|
/// For a single sample, [`Rng::random_range`] may be preferred:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use rand::Rng;
|
/// use rand::Rng;
|
||||||
///
|
///
|
||||||
/// let mut rng = rand::rng();
|
/// let mut rng = rand::rng();
|
||||||
/// println!("{}", rng.gen_range(0..10));
|
/// println!("{}", rng.random_range(0..10));
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`new`]: Uniform::new
|
/// [`new`]: Uniform::new
|
||||||
/// [`new_inclusive`]: Uniform::new_inclusive
|
/// [`new_inclusive`]: Uniform::new_inclusive
|
||||||
/// [`Rng::gen_range`]: Rng::gen_range
|
/// [`Rng::random_range`]: Rng::random_range
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(bound(serialize = "X::Sampler: Serialize")))]
|
#[cfg_attr(feature = "serde", serde(bound(serialize = "X::Sampler: Serialize")))]
|
||||||
@ -406,7 +406,7 @@ where
|
|||||||
/// Range that supports generating a single sample efficiently.
|
/// Range that supports generating a single sample efficiently.
|
||||||
///
|
///
|
||||||
/// Any type implementing this trait can be used to specify the sampled range
|
/// Any type implementing this trait can be used to specify the sampled range
|
||||||
/// for `Rng::gen_range`.
|
/// for `Rng::random_range`.
|
||||||
pub trait SampleRange<T> {
|
pub trait SampleRange<T> {
|
||||||
/// Generate a sample from the given range.
|
/// Generate a sample from the given range.
|
||||||
fn sample_single<R: RngCore + ?Sized>(self, rng: &mut R) -> Result<T, Error>;
|
fn sample_single<R: RngCore + ?Sized>(self, rng: &mut R) -> Result<T, Error>;
|
||||||
|
@ -364,7 +364,7 @@ mod tests {
|
|||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_float_overflow_single() {
|
fn test_float_overflow_single() {
|
||||||
let mut rng = crate::test::rng(252);
|
let mut rng = crate::test::rng(252);
|
||||||
rng.gen_range(f64::MIN..f64::MAX);
|
rng.random_range(f64::MIN..f64::MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -265,7 +265,7 @@ mod tests {
|
|||||||
let mut rng = crate::test::rng(891);
|
let mut rng = crate::test::rng(891);
|
||||||
let mut max = core::char::from_u32(0).unwrap();
|
let mut max = core::char::from_u32(0).unwrap();
|
||||||
for _ in 0..100 {
|
for _ in 0..100 {
|
||||||
let c = rng.gen_range('A'..='Z');
|
let c = rng.random_range('A'..='Z');
|
||||||
assert!(c.is_ascii_uppercase());
|
assert!(c.is_ascii_uppercase());
|
||||||
max = max.max(c);
|
max = max.max(c);
|
||||||
}
|
}
|
||||||
|
285
src/rng.rs
285
src/rng.rs
@ -125,6 +125,111 @@ pub trait Rng: RngCore {
|
|||||||
Standard.sample_iter(self)
|
Standard.sample_iter(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate a random value in the given range.
|
||||||
|
///
|
||||||
|
/// This function is optimised for the case that only a single sample is
|
||||||
|
/// made from the given range. See also the [`Uniform`] distribution
|
||||||
|
/// type which may be faster if sampling from the same range repeatedly.
|
||||||
|
///
|
||||||
|
/// All types support `low..high_exclusive` and `low..=high` range syntax.
|
||||||
|
/// Unsigned integer types also support `..high_exclusive` and `..=high` syntax.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the range is empty, or if `high - low` overflows for floats.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use rand::Rng;
|
||||||
|
///
|
||||||
|
/// let mut rng = rand::rng();
|
||||||
|
///
|
||||||
|
/// // Exclusive range
|
||||||
|
/// let n: u32 = rng.random_range(..10);
|
||||||
|
/// println!("{}", n);
|
||||||
|
/// let m: f64 = rng.random_range(-40.0..1.3e5);
|
||||||
|
/// println!("{}", m);
|
||||||
|
///
|
||||||
|
/// // Inclusive range
|
||||||
|
/// let n: u32 = rng.random_range(..=10);
|
||||||
|
/// println!("{}", n);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [`Uniform`]: distr::uniform::Uniform
|
||||||
|
#[track_caller]
|
||||||
|
fn random_range<T, R>(&mut self, range: R) -> T
|
||||||
|
where
|
||||||
|
T: SampleUniform,
|
||||||
|
R: SampleRange<T>,
|
||||||
|
{
|
||||||
|
assert!(!range.is_empty(), "cannot sample empty range");
|
||||||
|
range.sample_single(self).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a bool with a probability `p` of being true.
|
||||||
|
///
|
||||||
|
/// See also the [`Bernoulli`] distribution, which may be faster if
|
||||||
|
/// sampling from the same probability repeatedly.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use rand::Rng;
|
||||||
|
///
|
||||||
|
/// let mut rng = rand::rng();
|
||||||
|
/// println!("{}", rng.random_bool(1.0 / 3.0));
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// If `p < 0` or `p > 1`.
|
||||||
|
///
|
||||||
|
/// [`Bernoulli`]: distr::Bernoulli
|
||||||
|
#[inline]
|
||||||
|
#[track_caller]
|
||||||
|
fn random_bool(&mut self, p: f64) -> bool {
|
||||||
|
match distr::Bernoulli::new(p) {
|
||||||
|
Ok(d) => self.sample(d),
|
||||||
|
Err(_) => panic!("p={:?} is outside range [0.0, 1.0]", p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a bool with a probability of `numerator/denominator` of being
|
||||||
|
/// true. I.e. `random_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
|
||||||
|
/// returning true. If `numerator == denominator`, then the returned value
|
||||||
|
/// is guaranteed to be `true`. If `numerator == 0`, then the returned
|
||||||
|
/// value is guaranteed to be `false`.
|
||||||
|
///
|
||||||
|
/// See also the [`Bernoulli`] distribution, which may be faster if
|
||||||
|
/// sampling from the same `numerator` and `denominator` repeatedly.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// If `denominator == 0` or `numerator > denominator`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use rand::Rng;
|
||||||
|
///
|
||||||
|
/// let mut rng = rand::rng();
|
||||||
|
/// println!("{}", rng.random_ratio(2, 3));
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [`Bernoulli`]: distr::Bernoulli
|
||||||
|
#[inline]
|
||||||
|
#[track_caller]
|
||||||
|
fn random_ratio(&mut self, numerator: u32, denominator: u32) -> bool {
|
||||||
|
match distr::Bernoulli::from_ratio(numerator, denominator) {
|
||||||
|
Ok(d) => self.sample(d),
|
||||||
|
Err(_) => panic!(
|
||||||
|
"p={}/{} is outside range [0.0, 1.0]",
|
||||||
|
numerator, denominator
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Sample a new value, using the given distribution.
|
/// Sample a new value, using the given distribution.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
@ -208,111 +313,6 @@ pub trait Rng: RngCore {
|
|||||||
dest.fill(self)
|
dest.fill(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a random value in the given range.
|
|
||||||
///
|
|
||||||
/// This function is optimised for the case that only a single sample is
|
|
||||||
/// made from the given range. See also the [`Uniform`] distribution
|
|
||||||
/// type which may be faster if sampling from the same range repeatedly.
|
|
||||||
///
|
|
||||||
/// All types support `low..high_exclusive` and `low..=high` range syntax.
|
|
||||||
/// Unsigned integer types also support `..high_exclusive` and `..=high` syntax.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if the range is empty, or if `high - low` overflows for floats.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rand::Rng;
|
|
||||||
///
|
|
||||||
/// let mut rng = rand::rng();
|
|
||||||
///
|
|
||||||
/// // Exclusive range
|
|
||||||
/// let n: u32 = rng.gen_range(..10);
|
|
||||||
/// println!("{}", n);
|
|
||||||
/// let m: f64 = rng.gen_range(-40.0..1.3e5);
|
|
||||||
/// println!("{}", m);
|
|
||||||
///
|
|
||||||
/// // Inclusive range
|
|
||||||
/// let n: u32 = rng.gen_range(..=10);
|
|
||||||
/// println!("{}", n);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// [`Uniform`]: distr::uniform::Uniform
|
|
||||||
#[track_caller]
|
|
||||||
fn gen_range<T, R>(&mut self, range: R) -> T
|
|
||||||
where
|
|
||||||
T: SampleUniform,
|
|
||||||
R: SampleRange<T>,
|
|
||||||
{
|
|
||||||
assert!(!range.is_empty(), "cannot sample empty range");
|
|
||||||
range.sample_single(self).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a bool with a probability `p` of being true.
|
|
||||||
///
|
|
||||||
/// See also the [`Bernoulli`] distribution, which may be faster if
|
|
||||||
/// sampling from the same probability repeatedly.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rand::Rng;
|
|
||||||
///
|
|
||||||
/// let mut rng = rand::rng();
|
|
||||||
/// println!("{}", rng.gen_bool(1.0 / 3.0));
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// If `p < 0` or `p > 1`.
|
|
||||||
///
|
|
||||||
/// [`Bernoulli`]: distr::Bernoulli
|
|
||||||
#[inline]
|
|
||||||
#[track_caller]
|
|
||||||
fn gen_bool(&mut self, p: f64) -> bool {
|
|
||||||
match distr::Bernoulli::new(p) {
|
|
||||||
Ok(d) => self.sample(d),
|
|
||||||
Err(_) => panic!("p={:?} is outside range [0.0, 1.0]", p),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a bool with a probability of `numerator/denominator` of being
|
|
||||||
/// true. I.e. `gen_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
|
|
||||||
/// returning true. If `numerator == denominator`, then the returned value
|
|
||||||
/// is guaranteed to be `true`. If `numerator == 0`, then the returned
|
|
||||||
/// value is guaranteed to be `false`.
|
|
||||||
///
|
|
||||||
/// See also the [`Bernoulli`] distribution, which may be faster if
|
|
||||||
/// sampling from the same `numerator` and `denominator` repeatedly.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// If `denominator == 0` or `numerator > denominator`.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rand::Rng;
|
|
||||||
///
|
|
||||||
/// let mut rng = rand::rng();
|
|
||||||
/// println!("{}", rng.gen_ratio(2, 3));
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// [`Bernoulli`]: distr::Bernoulli
|
|
||||||
#[inline]
|
|
||||||
#[track_caller]
|
|
||||||
fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool {
|
|
||||||
match distr::Bernoulli::from_ratio(numerator, denominator) {
|
|
||||||
Ok(d) => self.sample(d),
|
|
||||||
Err(_) => panic!(
|
|
||||||
"p={}/{} is outside range [0.0, 1.0]",
|
|
||||||
numerator, denominator
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Alias for [`Rng::random`].
|
/// Alias for [`Rng::random`].
|
||||||
#[inline]
|
#[inline]
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
@ -325,6 +325,31 @@ pub trait Rng: RngCore {
|
|||||||
{
|
{
|
||||||
self.random()
|
self.random()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Alias for [`Rng::random_range`].
|
||||||
|
#[inline]
|
||||||
|
#[deprecated(since = "0.9.0", note = "Renamed to `random_range`")]
|
||||||
|
fn gen_range<T, R>(&mut self, range: R) -> T
|
||||||
|
where
|
||||||
|
T: SampleUniform,
|
||||||
|
R: SampleRange<T>,
|
||||||
|
{
|
||||||
|
self.random_range(range)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Alias for [`Rng::random_bool`].
|
||||||
|
#[inline]
|
||||||
|
#[deprecated(since = "0.9.0", note = "Renamed to `random_bool`")]
|
||||||
|
fn gen_bool(&mut self, p: f64) -> bool {
|
||||||
|
self.random_bool(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Alias for [`Rng::random_ratio`].
|
||||||
|
#[inline]
|
||||||
|
#[deprecated(since = "0.9.0", note = "Renamed to `random_ratio`")]
|
||||||
|
fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool {
|
||||||
|
self.random_ratio(numerator, denominator)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RngCore + ?Sized> Rng for R {}
|
impl<R: RngCore + ?Sized> Rng for R {}
|
||||||
@ -480,64 +505,64 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gen_range_int() {
|
fn test_random_range_int() {
|
||||||
let mut r = rng(101);
|
let mut r = rng(101);
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
let a = r.gen_range(-4711..17);
|
let a = r.random_range(-4711..17);
|
||||||
assert!((-4711..17).contains(&a));
|
assert!((-4711..17).contains(&a));
|
||||||
let a: i8 = r.gen_range(-3..42);
|
let a: i8 = r.random_range(-3..42);
|
||||||
assert!((-3..42).contains(&a));
|
assert!((-3..42).contains(&a));
|
||||||
let a: u16 = r.gen_range(10..99);
|
let a: u16 = r.random_range(10..99);
|
||||||
assert!((10..99).contains(&a));
|
assert!((10..99).contains(&a));
|
||||||
let a: i32 = r.gen_range(-100..2000);
|
let a: i32 = r.random_range(-100..2000);
|
||||||
assert!((-100..2000).contains(&a));
|
assert!((-100..2000).contains(&a));
|
||||||
let a: u32 = r.gen_range(12..=24);
|
let a: u32 = r.random_range(12..=24);
|
||||||
assert!((12..=24).contains(&a));
|
assert!((12..=24).contains(&a));
|
||||||
|
|
||||||
assert_eq!(r.gen_range(..1u32), 0u32);
|
assert_eq!(r.random_range(..1u32), 0u32);
|
||||||
assert_eq!(r.gen_range(-12i64..-11), -12i64);
|
assert_eq!(r.random_range(-12i64..-11), -12i64);
|
||||||
assert_eq!(r.gen_range(3_000_000..3_000_001), 3_000_000);
|
assert_eq!(r.random_range(3_000_000..3_000_001), 3_000_000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gen_range_float() {
|
fn test_random_range_float() {
|
||||||
let mut r = rng(101);
|
let mut r = rng(101);
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
let a = r.gen_range(-4.5..1.7);
|
let a = r.random_range(-4.5..1.7);
|
||||||
assert!((-4.5..1.7).contains(&a));
|
assert!((-4.5..1.7).contains(&a));
|
||||||
let a = r.gen_range(-1.1..=-0.3);
|
let a = r.random_range(-1.1..=-0.3);
|
||||||
assert!((-1.1..=-0.3).contains(&a));
|
assert!((-1.1..=-0.3).contains(&a));
|
||||||
|
|
||||||
assert_eq!(r.gen_range(0.0f32..=0.0), 0.);
|
assert_eq!(r.random_range(0.0f32..=0.0), 0.);
|
||||||
assert_eq!(r.gen_range(-11.0..=-11.0), -11.);
|
assert_eq!(r.random_range(-11.0..=-11.0), -11.);
|
||||||
assert_eq!(r.gen_range(3_000_000.0..=3_000_000.0), 3_000_000.);
|
assert_eq!(r.random_range(3_000_000.0..=3_000_000.0), 3_000_000.);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
#[allow(clippy::reversed_empty_ranges)]
|
#[allow(clippy::reversed_empty_ranges)]
|
||||||
fn test_gen_range_panic_int() {
|
fn test_random_range_panic_int() {
|
||||||
let mut r = rng(102);
|
let mut r = rng(102);
|
||||||
r.gen_range(5..-2);
|
r.random_range(5..-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
#[allow(clippy::reversed_empty_ranges)]
|
#[allow(clippy::reversed_empty_ranges)]
|
||||||
fn test_gen_range_panic_usize() {
|
fn test_random_range_panic_usize() {
|
||||||
let mut r = rng(103);
|
let mut r = rng(103);
|
||||||
r.gen_range(5..2);
|
r.random_range(5..2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(clippy::bool_assert_comparison)]
|
#[allow(clippy::bool_assert_comparison)]
|
||||||
fn test_gen_bool() {
|
fn test_random_bool() {
|
||||||
let mut r = rng(105);
|
let mut r = rng(105);
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
assert_eq!(r.gen_bool(0.0), false);
|
assert_eq!(r.random_bool(0.0), false);
|
||||||
assert_eq!(r.gen_bool(1.0), true);
|
assert_eq!(r.random_bool(1.0), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,7 +583,7 @@ mod test {
|
|||||||
let mut r = &mut rng as &mut dyn RngCore;
|
let mut r = &mut rng as &mut dyn RngCore;
|
||||||
r.next_u32();
|
r.next_u32();
|
||||||
r.random::<i32>();
|
r.random::<i32>();
|
||||||
assert_eq!(r.gen_range(0..1), 0);
|
assert_eq!(r.random_range(0..1), 0);
|
||||||
let _c: u8 = Standard.sample(&mut r);
|
let _c: u8 = Standard.sample(&mut r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,7 +595,7 @@ mod test {
|
|||||||
let mut r = Box::new(rng) as Box<dyn RngCore>;
|
let mut r = Box::new(rng) as Box<dyn RngCore>;
|
||||||
r.next_u32();
|
r.next_u32();
|
||||||
r.random::<i32>();
|
r.random::<i32>();
|
||||||
assert_eq!(r.gen_range(0..1), 0);
|
assert_eq!(r.random_range(0..1), 0);
|
||||||
let _c: u8 = Standard.sample(&mut r);
|
let _c: u8 = Standard.sample(&mut r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,7 +609,7 @@ mod test {
|
|||||||
let mut sum: u32 = 0;
|
let mut sum: u32 = 0;
|
||||||
let mut rng = rng(111);
|
let mut rng = rng(111);
|
||||||
for _ in 0..N {
|
for _ in 0..N {
|
||||||
if rng.gen_ratio(NUM, DENOM) {
|
if rng.random_ratio(NUM, DENOM) {
|
||||||
sum += 1;
|
sum += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ thread_local!(
|
|||||||
/// let mut rng = rand::rng();
|
/// let mut rng = rand::rng();
|
||||||
///
|
///
|
||||||
/// println!("True or false: {}", rng.random::<bool>());
|
/// println!("True or false: {}", rng.random::<bool>());
|
||||||
/// println!("A simulated die roll: {}", rng.gen_range(1..=6));
|
/// println!("A simulated die roll: {}", rng.random_range(1..=6));
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn rng() -> ThreadRng {
|
pub fn rng() -> ThreadRng {
|
||||||
@ -185,7 +185,7 @@ mod test {
|
|||||||
use crate::Rng;
|
use crate::Rng;
|
||||||
let mut r = crate::rng();
|
let mut r = crate::rng();
|
||||||
r.random::<i32>();
|
r.random::<i32>();
|
||||||
assert_eq!(r.gen_range(0..1), 0);
|
assert_eq!(r.random_range(0..1), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -27,17 +27,17 @@ impl<R: RngCore> CoinFlipper<R> {
|
|||||||
/// Returns true with a probability of 1 / d
|
/// Returns true with a probability of 1 / d
|
||||||
/// Uses an expected two bits of randomness
|
/// Uses an expected two bits of randomness
|
||||||
/// Panics if d == 0
|
/// Panics if d == 0
|
||||||
pub fn gen_ratio_one_over(&mut self, d: usize) -> bool {
|
pub fn random_ratio_one_over(&mut self, d: usize) -> bool {
|
||||||
debug_assert_ne!(d, 0);
|
debug_assert_ne!(d, 0);
|
||||||
// This uses the same logic as `gen_ratio` but is optimized for the case that
|
// This uses the same logic as `random_ratio` but is optimized for the case that
|
||||||
// the starting numerator is one (which it always is for `Sequence::Choose()`)
|
// the starting numerator is one (which it always is for `Sequence::Choose()`)
|
||||||
|
|
||||||
// In this case (but not `gen_ratio`), this way of calculating c is always accurate
|
// In this case (but not `random_ratio`), this way of calculating c is always accurate
|
||||||
let c = (usize::BITS - 1 - d.leading_zeros()).min(32);
|
let c = (usize::BITS - 1 - d.leading_zeros()).min(32);
|
||||||
|
|
||||||
if self.flip_c_heads(c) {
|
if self.flip_c_heads(c) {
|
||||||
let numerator = 1 << c;
|
let numerator = 1 << c;
|
||||||
self.gen_ratio(numerator, d)
|
self.random_ratio(numerator, d)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ impl<R: RngCore> CoinFlipper<R> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
/// Returns true with a probability of n / d
|
/// Returns true with a probability of n / d
|
||||||
/// Uses an expected two bits of randomness
|
/// Uses an expected two bits of randomness
|
||||||
fn gen_ratio(&mut self, mut n: usize, d: usize) -> bool {
|
fn random_ratio(&mut self, mut n: usize, d: usize) -> bool {
|
||||||
// Explanation:
|
// Explanation:
|
||||||
// We are trying to return true with a probability of n / d
|
// We are trying to return true with a probability of n / d
|
||||||
// If n >= d, we can just return true
|
// If n >= d, we can just return true
|
||||||
|
@ -41,7 +41,7 @@ impl<R: RngCore> IncreasingUniform<R> {
|
|||||||
let next_n = self.n + 1;
|
let next_n = self.n + 1;
|
||||||
|
|
||||||
// There's room for further optimisation here:
|
// There's room for further optimisation here:
|
||||||
// gen_range uses rejection sampling (or other method; see #1196) to avoid bias.
|
// random_range uses rejection sampling (or other method; see #1196) to avoid bias.
|
||||||
// When the initial sample is biased for range 0..bound
|
// When the initial sample is biased for range 0..bound
|
||||||
// it may still be viable to use for a smaller bound
|
// it may still be viable to use for a smaller bound
|
||||||
// (especially if small biases are considered acceptable).
|
// (especially if small biases are considered acceptable).
|
||||||
@ -50,7 +50,7 @@ impl<R: RngCore> IncreasingUniform<R> {
|
|||||||
// If the chunk is empty, generate a new chunk
|
// If the chunk is empty, generate a new chunk
|
||||||
let (bound, remaining) = calculate_bound_u32(next_n);
|
let (bound, remaining) = calculate_bound_u32(next_n);
|
||||||
// bound = (n + 1) * (n + 2) *..* (n + remaining)
|
// bound = (n + 1) * (n + 2) *..* (n + remaining)
|
||||||
self.chunk = self.rng.gen_range(0..bound);
|
self.chunk = self.rng.random_range(..bound);
|
||||||
// Chunk is a random number in
|
// Chunk is a random number in
|
||||||
// [0, (n + 1) * (n + 2) *..* (n + remaining) )
|
// [0, (n + 1) * (n + 2) *..* (n + remaining) )
|
||||||
|
|
||||||
|
@ -430,13 +430,13 @@ fn sample_floyd<R>(rng: &mut R, length: u32, amount: u32) -> IndexVec
|
|||||||
where
|
where
|
||||||
R: Rng + ?Sized,
|
R: Rng + ?Sized,
|
||||||
{
|
{
|
||||||
// Note that the values returned by `rng.gen_range()` can be
|
// Note that the values returned by `rng.random_range()` can be
|
||||||
// inferred from the returned vector by working backwards from
|
// inferred from the returned vector by working backwards from
|
||||||
// the last entry. This bijection proves the algorithm fair.
|
// the last entry. This bijection proves the algorithm fair.
|
||||||
debug_assert!(amount <= length);
|
debug_assert!(amount <= length);
|
||||||
let mut indices = Vec::with_capacity(amount as usize);
|
let mut indices = Vec::with_capacity(amount as usize);
|
||||||
for j in length - amount..length {
|
for j in length - amount..length {
|
||||||
let t = rng.gen_range(..=j);
|
let t = rng.random_range(..=j);
|
||||||
if let Some(pos) = indices.iter().position(|&x| x == t) {
|
if let Some(pos) = indices.iter().position(|&x| x == t) {
|
||||||
indices[pos] = j;
|
indices[pos] = j;
|
||||||
}
|
}
|
||||||
@ -465,7 +465,7 @@ where
|
|||||||
let mut indices: Vec<u32> = Vec::with_capacity(length as usize);
|
let mut indices: Vec<u32> = Vec::with_capacity(length as usize);
|
||||||
indices.extend(0..length);
|
indices.extend(0..length);
|
||||||
for i in 0..amount {
|
for i in 0..amount {
|
||||||
let j: u32 = rng.gen_range(i..length);
|
let j: u32 = rng.random_range(i..length);
|
||||||
indices.swap(i as usize, j as usize);
|
indices.swap(i as usize, j as usize);
|
||||||
}
|
}
|
||||||
indices.truncate(amount as usize);
|
indices.truncate(amount as usize);
|
||||||
|
@ -68,7 +68,7 @@ pub trait IteratorRandom: Iterator + Sized {
|
|||||||
return match lower {
|
return match lower {
|
||||||
0 => None,
|
0 => None,
|
||||||
1 => self.next(),
|
1 => self.next(),
|
||||||
_ => self.nth(rng.gen_range(..lower)),
|
_ => self.nth(rng.random_range(..lower)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ pub trait IteratorRandom: Iterator + Sized {
|
|||||||
// Continue until the iterator is exhausted
|
// Continue until the iterator is exhausted
|
||||||
loop {
|
loop {
|
||||||
if lower > 1 {
|
if lower > 1 {
|
||||||
let ix = coin_flipper.rng.gen_range(..lower + consumed);
|
let ix = coin_flipper.rng.random_range(..lower + consumed);
|
||||||
let skip = if ix < lower {
|
let skip = if ix < lower {
|
||||||
result = self.nth(ix);
|
result = self.nth(ix);
|
||||||
lower - (ix + 1)
|
lower - (ix + 1)
|
||||||
@ -98,7 +98,7 @@ pub trait IteratorRandom: Iterator + Sized {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
consumed += 1;
|
consumed += 1;
|
||||||
if coin_flipper.gen_ratio_one_over(consumed) {
|
if coin_flipper.random_ratio_one_over(consumed) {
|
||||||
result = elem;
|
result = elem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ pub trait IteratorRandom: Iterator + Sized {
|
|||||||
let (lower, _) = self.size_hint();
|
let (lower, _) = self.size_hint();
|
||||||
if lower >= 2 {
|
if lower >= 2 {
|
||||||
let highest_selected = (0..lower)
|
let highest_selected = (0..lower)
|
||||||
.filter(|ix| coin_flipper.gen_ratio_one_over(consumed + ix + 1))
|
.filter(|ix| coin_flipper.random_ratio_one_over(consumed + ix + 1))
|
||||||
.last();
|
.last();
|
||||||
|
|
||||||
consumed += lower;
|
consumed += lower;
|
||||||
@ -161,7 +161,7 @@ pub trait IteratorRandom: Iterator + Sized {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if coin_flipper.gen_ratio_one_over(consumed + 1) {
|
if coin_flipper.random_ratio_one_over(consumed + 1) {
|
||||||
result = elem;
|
result = elem;
|
||||||
}
|
}
|
||||||
consumed += 1;
|
consumed += 1;
|
||||||
@ -201,7 +201,7 @@ pub trait IteratorRandom: Iterator + Sized {
|
|||||||
|
|
||||||
// Continue, since the iterator was not exhausted
|
// Continue, since the iterator was not exhausted
|
||||||
for (i, elem) in self.enumerate() {
|
for (i, elem) in self.enumerate() {
|
||||||
let k = rng.gen_range(..i + 1 + amount);
|
let k = rng.random_range(..i + 1 + amount);
|
||||||
if let Some(slot) = buf.get_mut(k) {
|
if let Some(slot) = buf.get_mut(k) {
|
||||||
*slot = elem;
|
*slot = elem;
|
||||||
}
|
}
|
||||||
@ -237,7 +237,7 @@ pub trait IteratorRandom: Iterator + Sized {
|
|||||||
// If the iterator stops once, then so do we.
|
// If the iterator stops once, then so do we.
|
||||||
if reservoir.len() == amount {
|
if reservoir.len() == amount {
|
||||||
for (i, elem) in self.enumerate() {
|
for (i, elem) in self.enumerate() {
|
||||||
let k = rng.gen_range(..i + 1 + amount);
|
let k = rng.random_range(..i + 1 + amount);
|
||||||
if let Some(slot) = reservoir.get_mut(k) {
|
if let Some(slot) = reservoir.get_mut(k) {
|
||||||
*slot = elem;
|
*slot = elem;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ pub mod index {
|
|||||||
// Floyd's algorithm
|
// Floyd's algorithm
|
||||||
let mut indices = [0; N];
|
let mut indices = [0; N];
|
||||||
for (i, j) in (len - N..len).enumerate() {
|
for (i, j) in (len - N..len).enumerate() {
|
||||||
let t = rng.gen_range(..j + 1);
|
let t = rng.random_range(..j + 1);
|
||||||
if let Some(pos) = indices[0..i].iter().position(|&x| x == t) {
|
if let Some(pos) = indices[0..i].iter().position(|&x| x == t) {
|
||||||
indices[pos] = j;
|
indices[pos] = j;
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ pub trait IndexedRandom: Index<usize> {
|
|||||||
if self.is_empty() {
|
if self.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(&self[rng.gen_range(..self.len())])
|
Some(&self[rng.random_range(..self.len())])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +258,7 @@ pub trait IndexedMutRandom: IndexedRandom + IndexMut<usize> {
|
|||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let len = self.len();
|
let len = self.len();
|
||||||
Some(&mut self[rng.gen_range(..len)])
|
Some(&mut self[rng.random_range(..len)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +397,7 @@ impl<T> SliceRandom for [T] {
|
|||||||
// It ensures that the last `amount` elements of the slice
|
// It ensures that the last `amount` elements of the slice
|
||||||
// are randomly selected from the whole slice.
|
// are randomly selected from the whole slice.
|
||||||
|
|
||||||
// `IncreasingUniform::next_index()` is faster than `Rng::gen_range`
|
// `IncreasingUniform::next_index()` is faster than `Rng::random_range`
|
||||||
// but only works for 32 bit integers
|
// but only works for 32 bit integers
|
||||||
// So we must use the slow method if the slice is longer than that.
|
// So we must use the slow method if the slice is longer than that.
|
||||||
if self.len() < (u32::MAX as usize) {
|
if self.len() < (u32::MAX as usize) {
|
||||||
@ -408,7 +408,7 @@ impl<T> SliceRandom for [T] {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for i in m..self.len() {
|
for i in m..self.len() {
|
||||||
let index = rng.gen_range(..i + 1);
|
let index = rng.random_range(..i + 1);
|
||||||
self.swap(i, index);
|
self.swap(i, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user