rand/
rng.rs

1// Copyright 2018 Developers of the Rand project.
2// Copyright 2013-2017 The Rust Project Developers.
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
10//! [`Rng`] trait
11
12use crate::distr::uniform::{SampleRange, SampleUniform};
13use crate::distr::{self, Distribution, StandardUniform};
14use core::num::Wrapping;
15use rand_core::RngCore;
16use zerocopy::IntoBytes;
17
18/// User-level interface for RNGs
19///
20/// [`RngCore`] is the `dyn`-safe implementation-level interface for Random
21/// (Number) Generators. This trait, `Rng`, provides a user-level interface on
22/// RNGs. It is implemented automatically for any `R: RngCore`.
23///
24/// This trait must usually be brought into scope via `use rand::Rng;` or
25/// `use rand::prelude::*;`.
26///
27/// # Generic usage
28///
29/// The basic pattern is `fn foo<R: Rng + ?Sized>(rng: &mut R)`. Some
30/// things are worth noting here:
31///
32/// - Since `Rng: RngCore` and every `RngCore` implements `Rng`, it makes no
33///   difference whether we use `R: Rng` or `R: RngCore`.
34/// - The `+ ?Sized` un-bounding allows functions to be called directly on
35///   type-erased references; i.e. `foo(r)` where `r: &mut dyn RngCore`. Without
36///   this it would be necessary to write `foo(&mut r)`.
37///
38/// An alternative pattern is possible: `fn foo<R: Rng>(rng: R)`. This has some
39/// trade-offs. It allows the argument to be consumed directly without a `&mut`
40/// (which is how `from_rng(rand::rng())` works); also it still works directly
41/// on references (including type-erased references). Unfortunately within the
42/// function `foo` it is not known whether `rng` is a reference type or not,
43/// hence many uses of `rng` require an extra reference, either explicitly
44/// (`distr.sample(&mut rng)`) or implicitly (`rng.random()`); one may hope the
45/// optimiser can remove redundant references later.
46///
47/// Example:
48///
49/// ```
50/// use rand::Rng;
51///
52/// fn foo<R: Rng + ?Sized>(rng: &mut R) -> f32 {
53///     rng.random()
54/// }
55///
56/// # let v = foo(&mut rand::rng());
57/// ```
58pub trait Rng: RngCore {
59    /// Return a random value via the [`StandardUniform`] distribution.
60    ///
61    /// # Example
62    ///
63    /// ```
64    /// use rand::Rng;
65    ///
66    /// let mut rng = rand::rng();
67    /// let x: u32 = rng.random();
68    /// println!("{}", x);
69    /// println!("{:?}", rng.random::<(f64, bool)>());
70    /// ```
71    ///
72    /// # Arrays and tuples
73    ///
74    /// The `rng.random()` method is able to generate arrays
75    /// and tuples (up to 12 elements), so long as all element types can be
76    /// generated.
77    ///
78    /// For arrays of integers, especially for those with small element types
79    /// (< 64 bit), it will likely be faster to instead use [`Rng::fill`],
80    /// though note that generated values will differ.
81    ///
82    /// ```
83    /// use rand::Rng;
84    ///
85    /// let mut rng = rand::rng();
86    /// let tuple: (u8, i32, char) = rng.random(); // arbitrary tuple support
87    ///
88    /// let arr1: [f32; 32] = rng.random();        // array construction
89    /// let mut arr2 = [0u8; 128];
90    /// rng.fill(&mut arr2);                    // array fill
91    /// ```
92    ///
93    /// [`StandardUniform`]: distr::StandardUniform
94    #[inline]
95    fn random<T>(&mut self) -> T
96    where
97        StandardUniform: Distribution<T>,
98    {
99        StandardUniform.sample(self)
100    }
101
102    /// Return an iterator over [`random`](Self::random) variates
103    ///
104    /// This is a just a wrapper over [`Rng::sample_iter`] using
105    /// [`distr::StandardUniform`].
106    ///
107    /// Note: this method consumes its argument. Use
108    /// `(&mut rng).random_iter()` to avoid consuming the RNG.
109    ///
110    /// # Example
111    ///
112    /// ```
113    /// use rand::{rngs::mock::StepRng, Rng};
114    ///
115    /// let rng = StepRng::new(1, 1);
116    /// let v: Vec<i32> = rng.random_iter().take(5).collect();
117    /// assert_eq!(&v, &[1, 2, 3, 4, 5]);
118    /// ```
119    #[inline]
120    fn random_iter<T>(self) -> distr::Iter<StandardUniform, Self, T>
121    where
122        Self: Sized,
123        StandardUniform: Distribution<T>,
124    {
125        StandardUniform.sample_iter(self)
126    }
127
128    /// Generate a random value in the given range.
129    ///
130    /// This function is optimised for the case that only a single sample is
131    /// made from the given range. See also the [`Uniform`] distribution
132    /// type which may be faster if sampling from the same range repeatedly.
133    ///
134    /// All types support `low..high_exclusive` and `low..=high` range syntax.
135    /// Unsigned integer types also support `..high_exclusive` and `..=high` syntax.
136    ///
137    /// # Panics
138    ///
139    /// Panics if the range is empty, or if `high - low` overflows for floats.
140    ///
141    /// # Example
142    ///
143    /// ```
144    /// use rand::Rng;
145    ///
146    /// let mut rng = rand::rng();
147    ///
148    /// // Exclusive range
149    /// let n: u32 = rng.random_range(..10);
150    /// println!("{}", n);
151    /// let m: f64 = rng.random_range(-40.0..1.3e5);
152    /// println!("{}", m);
153    ///
154    /// // Inclusive range
155    /// let n: u32 = rng.random_range(..=10);
156    /// println!("{}", n);
157    /// ```
158    ///
159    /// [`Uniform`]: distr::uniform::Uniform
160    #[track_caller]
161    fn random_range<T, R>(&mut self, range: R) -> T
162    where
163        T: SampleUniform,
164        R: SampleRange<T>,
165    {
166        assert!(!range.is_empty(), "cannot sample empty range");
167        range.sample_single(self).unwrap()
168    }
169
170    /// Return a bool with a probability `p` of being true.
171    ///
172    /// See also the [`Bernoulli`] distribution, which may be faster if
173    /// sampling from the same probability repeatedly.
174    ///
175    /// # Example
176    ///
177    /// ```
178    /// use rand::Rng;
179    ///
180    /// let mut rng = rand::rng();
181    /// println!("{}", rng.random_bool(1.0 / 3.0));
182    /// ```
183    ///
184    /// # Panics
185    ///
186    /// If `p < 0` or `p > 1`.
187    ///
188    /// [`Bernoulli`]: distr::Bernoulli
189    #[inline]
190    #[track_caller]
191    fn random_bool(&mut self, p: f64) -> bool {
192        match distr::Bernoulli::new(p) {
193            Ok(d) => self.sample(d),
194            Err(_) => panic!("p={:?} is outside range [0.0, 1.0]", p),
195        }
196    }
197
198    /// Return a bool with a probability of `numerator/denominator` of being
199    /// true.
200    ///
201    /// That is, `random_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
202    /// returning true. If `numerator == denominator`, then the returned value
203    /// is guaranteed to be `true`. If `numerator == 0`, then the returned
204    /// value is guaranteed to be `false`.
205    ///
206    /// See also the [`Bernoulli`] distribution, which may be faster if
207    /// sampling from the same `numerator` and `denominator` repeatedly.
208    ///
209    /// # Panics
210    ///
211    /// If `denominator == 0` or `numerator > denominator`.
212    ///
213    /// # Example
214    ///
215    /// ```
216    /// use rand::Rng;
217    ///
218    /// let mut rng = rand::rng();
219    /// println!("{}", rng.random_ratio(2, 3));
220    /// ```
221    ///
222    /// [`Bernoulli`]: distr::Bernoulli
223    #[inline]
224    #[track_caller]
225    fn random_ratio(&mut self, numerator: u32, denominator: u32) -> bool {
226        match distr::Bernoulli::from_ratio(numerator, denominator) {
227            Ok(d) => self.sample(d),
228            Err(_) => panic!(
229                "p={}/{} is outside range [0.0, 1.0]",
230                numerator, denominator
231            ),
232        }
233    }
234
235    /// Sample a new value, using the given distribution.
236    ///
237    /// ### Example
238    ///
239    /// ```
240    /// use rand::Rng;
241    /// use rand::distr::Uniform;
242    ///
243    /// let mut rng = rand::rng();
244    /// let x = rng.sample(Uniform::new(10u32, 15).unwrap());
245    /// // Type annotation requires two types, the type and distribution; the
246    /// // distribution can be inferred.
247    /// let y = rng.sample::<u16, _>(Uniform::new(10, 15).unwrap());
248    /// ```
249    fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T {
250        distr.sample(self)
251    }
252
253    /// Create an iterator that generates values using the given distribution.
254    ///
255    /// Note: this method consumes its arguments. Use
256    /// `(&mut rng).sample_iter(..)` to avoid consuming the RNG.
257    ///
258    /// # Example
259    ///
260    /// ```
261    /// use rand::Rng;
262    /// use rand::distr::{Alphanumeric, Uniform, StandardUniform};
263    ///
264    /// let mut rng = rand::rng();
265    ///
266    /// // Vec of 16 x f32:
267    /// let v: Vec<f32> = (&mut rng).sample_iter(StandardUniform).take(16).collect();
268    ///
269    /// // String:
270    /// let s: String = (&mut rng).sample_iter(Alphanumeric)
271    ///     .take(7)
272    ///     .map(char::from)
273    ///     .collect();
274    ///
275    /// // Combined values
276    /// println!("{:?}", (&mut rng).sample_iter(StandardUniform).take(5)
277    ///                              .collect::<Vec<(f64, bool)>>());
278    ///
279    /// // Dice-rolling:
280    /// let die_range = Uniform::new_inclusive(1, 6).unwrap();
281    /// let mut roll_die = (&mut rng).sample_iter(die_range);
282    /// while roll_die.next().unwrap() != 6 {
283    ///     println!("Not a 6; rolling again!");
284    /// }
285    /// ```
286    fn sample_iter<T, D>(self, distr: D) -> distr::Iter<D, Self, T>
287    where
288        D: Distribution<T>,
289        Self: Sized,
290    {
291        distr.sample_iter(self)
292    }
293
294    /// Fill any type implementing [`Fill`] with random data
295    ///
296    /// This method is implemented for types which may be safely reinterpreted
297    /// as an (aligned) `[u8]` slice then filled with random data. It is often
298    /// faster than using [`Rng::random`] but not value-equivalent.
299    ///
300    /// The distribution is expected to be uniform with portable results, but
301    /// this cannot be guaranteed for third-party implementations.
302    ///
303    /// # Example
304    ///
305    /// ```
306    /// use rand::Rng;
307    ///
308    /// let mut arr = [0i8; 20];
309    /// rand::rng().fill(&mut arr[..]);
310    /// ```
311    ///
312    /// [`fill_bytes`]: RngCore::fill_bytes
313    #[track_caller]
314    fn fill<T: Fill + ?Sized>(&mut self, dest: &mut T) {
315        dest.fill(self)
316    }
317
318    /// Alias for [`Rng::random`].
319    #[inline]
320    #[deprecated(
321        since = "0.9.0",
322        note = "Renamed to `random` to avoid conflict with the new `gen` keyword in Rust 2024."
323    )]
324    fn r#gen<T>(&mut self) -> T
325    where
326        StandardUniform: Distribution<T>,
327    {
328        self.random()
329    }
330
331    /// Alias for [`Rng::random_range`].
332    #[inline]
333    #[deprecated(since = "0.9.0", note = "Renamed to `random_range`")]
334    fn gen_range<T, R>(&mut self, range: R) -> T
335    where
336        T: SampleUniform,
337        R: SampleRange<T>,
338    {
339        self.random_range(range)
340    }
341
342    /// Alias for [`Rng::random_bool`].
343    #[inline]
344    #[deprecated(since = "0.9.0", note = "Renamed to `random_bool`")]
345    fn gen_bool(&mut self, p: f64) -> bool {
346        self.random_bool(p)
347    }
348
349    /// Alias for [`Rng::random_ratio`].
350    #[inline]
351    #[deprecated(since = "0.9.0", note = "Renamed to `random_ratio`")]
352    fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool {
353        self.random_ratio(numerator, denominator)
354    }
355}
356
357impl<R: RngCore + ?Sized> Rng for R {}
358
359/// Types which may be filled with random data
360///
361/// This trait allows arrays to be efficiently filled with random data.
362///
363/// Implementations are expected to be portable across machines unless
364/// clearly documented otherwise (see the
365/// [Chapter on Portability](https://rust-random.github.io/book/portability.html)).
366pub trait Fill {
367    /// Fill self with random data
368    fn fill<R: Rng + ?Sized>(&mut self, rng: &mut R);
369}
370
371macro_rules! impl_fill_each {
372    () => {};
373    ($t:ty) => {
374        impl Fill for [$t] {
375            fn fill<R: Rng + ?Sized>(&mut self, rng: &mut R) {
376                for elt in self.iter_mut() {
377                    *elt = rng.random();
378                }
379            }
380        }
381    };
382    ($t:ty, $($tt:ty,)*) => {
383        impl_fill_each!($t);
384        impl_fill_each!($($tt,)*);
385    };
386}
387
388impl_fill_each!(bool, char, f32, f64,);
389
390impl Fill for [u8] {
391    fn fill<R: Rng + ?Sized>(&mut self, rng: &mut R) {
392        rng.fill_bytes(self)
393    }
394}
395
396macro_rules! impl_fill {
397    () => {};
398    ($t:ty) => {
399        impl Fill for [$t] {
400            #[inline(never)] // in micro benchmarks, this improves performance
401            fn fill<R: Rng + ?Sized>(&mut self, rng: &mut R) {
402                if self.len() > 0 {
403                    rng.fill_bytes(self.as_mut_bytes());
404                    for x in self {
405                        *x = x.to_le();
406                    }
407                }
408            }
409        }
410
411        impl Fill for [Wrapping<$t>] {
412            #[inline(never)]
413            fn fill<R: Rng + ?Sized>(&mut self, rng: &mut R) {
414                if self.len() > 0 {
415                    rng.fill_bytes(self.as_mut_bytes());
416                    for x in self {
417                    *x = Wrapping(x.0.to_le());
418                    }
419                }
420            }
421        }
422    };
423    ($t:ty, $($tt:ty,)*) => {
424        impl_fill!($t);
425        // TODO: this could replace above impl once Rust #32463 is fixed
426        // impl_fill!(Wrapping<$t>);
427        impl_fill!($($tt,)*);
428    }
429}
430
431impl_fill!(u16, u32, u64, u128,);
432impl_fill!(i8, i16, i32, i64, i128,);
433
434impl<T, const N: usize> Fill for [T; N]
435where
436    [T]: Fill,
437{
438    fn fill<R: Rng + ?Sized>(&mut self, rng: &mut R) {
439        <[T] as Fill>::fill(self, rng)
440    }
441}
442
443#[cfg(test)]
444mod test {
445    use super::*;
446    use crate::rngs::mock::StepRng;
447    use crate::test::rng;
448    #[cfg(feature = "alloc")]
449    use alloc::boxed::Box;
450
451    #[test]
452    fn test_fill_bytes_default() {
453        let mut r = StepRng::new(0x11_22_33_44_55_66_77_88, 0);
454
455        // check every remainder mod 8, both in small and big vectors.
456        let lengths = [0, 1, 2, 3, 4, 5, 6, 7, 80, 81, 82, 83, 84, 85, 86, 87];
457        for &n in lengths.iter() {
458            let mut buffer = [0u8; 87];
459            let v = &mut buffer[0..n];
460            r.fill_bytes(v);
461
462            // use this to get nicer error messages.
463            for (i, &byte) in v.iter().enumerate() {
464                if byte == 0 {
465                    panic!("byte {} of {} is zero", i, n)
466                }
467            }
468        }
469    }
470
471    #[test]
472    fn test_fill() {
473        let x = 9041086907909331047; // a random u64
474        let mut rng = StepRng::new(x, 0);
475
476        // Convert to byte sequence and back to u64; byte-swap twice if BE.
477        let mut array = [0u64; 2];
478        rng.fill(&mut array[..]);
479        assert_eq!(array, [x, x]);
480        assert_eq!(rng.next_u64(), x);
481
482        // Convert to bytes then u32 in LE order
483        let mut array = [0u32; 2];
484        rng.fill(&mut array[..]);
485        assert_eq!(array, [x as u32, (x >> 32) as u32]);
486        assert_eq!(rng.next_u32(), x as u32);
487
488        // Check equivalence using wrapped arrays
489        let mut warray = [Wrapping(0u32); 2];
490        rng.fill(&mut warray[..]);
491        assert_eq!(array[0], warray[0].0);
492        assert_eq!(array[1], warray[1].0);
493
494        // Check equivalence for generated floats
495        let mut array = [0f32; 2];
496        rng.fill(&mut array);
497        let arr2: [f32; 2] = rng.random();
498        assert_eq!(array, arr2);
499    }
500
501    #[test]
502    fn test_fill_empty() {
503        let mut array = [0u32; 0];
504        let mut rng = StepRng::new(0, 1);
505        rng.fill(&mut array);
506        rng.fill(&mut array[..]);
507    }
508
509    #[test]
510    fn test_random_range_int() {
511        let mut r = rng(101);
512        for _ in 0..1000 {
513            let a = r.random_range(-4711..17);
514            assert!((-4711..17).contains(&a));
515            let a: i8 = r.random_range(-3..42);
516            assert!((-3..42).contains(&a));
517            let a: u16 = r.random_range(10..99);
518            assert!((10..99).contains(&a));
519            let a: i32 = r.random_range(-100..2000);
520            assert!((-100..2000).contains(&a));
521            let a: u32 = r.random_range(12..=24);
522            assert!((12..=24).contains(&a));
523
524            assert_eq!(r.random_range(..1u32), 0u32);
525            assert_eq!(r.random_range(-12i64..-11), -12i64);
526            assert_eq!(r.random_range(3_000_000..3_000_001), 3_000_000);
527        }
528    }
529
530    #[test]
531    fn test_random_range_float() {
532        let mut r = rng(101);
533        for _ in 0..1000 {
534            let a = r.random_range(-4.5..1.7);
535            assert!((-4.5..1.7).contains(&a));
536            let a = r.random_range(-1.1..=-0.3);
537            assert!((-1.1..=-0.3).contains(&a));
538
539            assert_eq!(r.random_range(0.0f32..=0.0), 0.);
540            assert_eq!(r.random_range(-11.0..=-11.0), -11.);
541            assert_eq!(r.random_range(3_000_000.0..=3_000_000.0), 3_000_000.);
542        }
543    }
544
545    #[test]
546    #[should_panic]
547    #[allow(clippy::reversed_empty_ranges)]
548    fn test_random_range_panic_int() {
549        let mut r = rng(102);
550        r.random_range(5..-2);
551    }
552
553    #[test]
554    #[should_panic]
555    #[allow(clippy::reversed_empty_ranges)]
556    fn test_random_range_panic_usize() {
557        let mut r = rng(103);
558        r.random_range(5..2);
559    }
560
561    #[test]
562    #[allow(clippy::bool_assert_comparison)]
563    fn test_random_bool() {
564        let mut r = rng(105);
565        for _ in 0..5 {
566            assert_eq!(r.random_bool(0.0), false);
567            assert_eq!(r.random_bool(1.0), true);
568        }
569    }
570
571    #[test]
572    fn test_rng_mut_ref() {
573        fn use_rng(mut r: impl Rng) {
574            let _ = r.next_u32();
575        }
576
577        let mut rng = rng(109);
578        use_rng(&mut rng);
579    }
580
581    #[test]
582    fn test_rng_trait_object() {
583        use crate::distr::{Distribution, StandardUniform};
584        let mut rng = rng(109);
585        let mut r = &mut rng as &mut dyn RngCore;
586        r.next_u32();
587        r.random::<i32>();
588        assert_eq!(r.random_range(0..1), 0);
589        let _c: u8 = StandardUniform.sample(&mut r);
590    }
591
592    #[test]
593    #[cfg(feature = "alloc")]
594    fn test_rng_boxed_trait() {
595        use crate::distr::{Distribution, StandardUniform};
596        let rng = rng(110);
597        let mut r = Box::new(rng) as Box<dyn RngCore>;
598        r.next_u32();
599        r.random::<i32>();
600        assert_eq!(r.random_range(0..1), 0);
601        let _c: u8 = StandardUniform.sample(&mut r);
602    }
603
604    #[test]
605    #[cfg_attr(miri, ignore)] // Miri is too slow
606    fn test_gen_ratio_average() {
607        const NUM: u32 = 3;
608        const DENOM: u32 = 10;
609        const N: u32 = 100_000;
610
611        let mut sum: u32 = 0;
612        let mut rng = rng(111);
613        for _ in 0..N {
614            if rng.random_ratio(NUM, DENOM) {
615                sum += 1;
616            }
617        }
618        // Have Binomial(N, NUM/DENOM) distribution
619        let expected = (NUM * N) / DENOM; // exact integer
620        assert!(((sum - expected) as i32).abs() < 500);
621    }
622}