Rng renames: gen_ → random_ (#1505)

This commit is contained in:
Diggory Hardy 2024-10-16 14:45:36 +01:00 committed by GitHub
parent 9d57b87e27
commit 8225d948b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 207 additions and 181 deletions

View File

@ -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)

View File

@ -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| {

View File

@ -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| {

View File

@ -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));

View File

@ -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.

View File

@ -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).

View File

@ -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>;

View File

@ -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]

View File

@ -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);
} }

View File

@ -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;
} }
} }

View File

@ -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]

View File

@ -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

View File

@ -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) )

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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);
} }
} }