Skip to main content

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