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 //! Utilities for random number generation
11 //!
12 //! Rand provides utilities to generate random numbers, to convert them to
13 //! useful types and distributions, and some randomness-related algorithms.
14 //!
15 //! # Quick Start
16 //!
17 //! To get you started quickly, the easiest and highest-level way to get
18 //! a random value is to use [`random()`]; alternatively you can use
19 //! [`thread_rng()`]. The [`Rng`] trait provides a useful API on all RNGs, while
20 //! the [`distributions`] and [`seq`] modules provide further
21 //! functionality on top of RNGs.
22 //!
23 //! ```
24 //! use rand::prelude::*;
25 //!
26 //! if rand::random() { // generates a boolean
27 //!     // Try printing a random unicode code point (probably a bad idea)!
28 //!     println!("char: {}", rand::random::<char>());
29 //! }
30 //!
31 //! let mut rng = rand::thread_rng();
32 //! let y: f64 = rng.gen(); // generates a float between 0 and 1
33 //!
34 //! let mut nums: Vec<i32> = (1..100).collect();
35 //! nums.shuffle(&mut rng);
36 //! ```
37 //!
38 //! # The Book
39 //!
40 //! For the user guide and futher documentation, please read
41 //! [The Rust Rand Book](https://rust-random.github.io/book).
42 
43 #![doc(
44     html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
45     html_favicon_url = "https://www.rust-lang.org/favicon.ico",
46     html_root_url = "https://rust-random.github.io/rand/"
47 )]
48 #![deny(missing_docs)]
49 #![deny(missing_debug_implementations)]
50 #![doc(test(attr(allow(unused_variables), deny(warnings))))]
51 #![cfg_attr(not(feature = "std"), no_std)]
52 #![cfg_attr(all(feature = "simd_support", feature = "nightly"), feature(stdsimd))]
53 #![allow(
54     clippy::excessive_precision,
55     clippy::unreadable_literal,
56     clippy::float_cmp
57 )]
58 
59 #[cfg(all(feature = "alloc", not(feature = "std")))] extern crate alloc;
60 
61 #[allow(unused)]
62 macro_rules! trace { ($($x:tt)*) => (
63     #[cfg(feature = "log")] {
64         log::trace!($($x)*)
65     }
66 ) }
67 #[allow(unused)]
68 macro_rules! debug { ($($x:tt)*) => (
69     #[cfg(feature = "log")] {
70         log::debug!($($x)*)
71     }
72 ) }
73 #[allow(unused)]
74 macro_rules! info { ($($x:tt)*) => (
75     #[cfg(feature = "log")] {
76         log::info!($($x)*)
77     }
78 ) }
79 #[allow(unused)]
80 macro_rules! warn { ($($x:tt)*) => (
81     #[cfg(feature = "log")] {
82         log::warn!($($x)*)
83     }
84 ) }
85 #[allow(unused)]
86 macro_rules! error { ($($x:tt)*) => (
87     #[cfg(feature = "log")] {
88         log::error!($($x)*)
89     }
90 ) }
91 
92 // Re-exports from rand_core
93 pub use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
94 
95 // Public exports
96 #[cfg(feature = "std")] pub use crate::rngs::thread::thread_rng;
97 
98 // Public modules
99 pub mod distributions;
100 pub mod prelude;
101 pub mod rngs;
102 pub mod seq;
103 
104 
105 use crate::distributions::uniform::{SampleBorrow, SampleUniform, UniformSampler};
106 use crate::distributions::{Distribution, Standard};
107 use core::num::Wrapping;
108 use core::{mem, slice};
109 
110 /// An automatically-implemented extension trait on [`RngCore`] providing high-level
111 /// generic methods for sampling values and other convenience methods.
112 ///
113 /// This is the primary trait to use when generating random values.
114 ///
115 /// # Generic usage
116 ///
117 /// The basic pattern is `fn foo<R: Rng + ?Sized>(rng: &mut R)`. Some
118 /// things are worth noting here:
119 ///
120 /// - Since `Rng: RngCore` and every `RngCore` implements `Rng`, it makes no
121 ///   difference whether we use `R: Rng` or `R: RngCore`.
122 /// - The `+ ?Sized` un-bounding allows functions to be called directly on
123 ///   type-erased references; i.e. `foo(r)` where `r: &mut RngCore`. Without
124 ///   this it would be necessary to write `foo(&mut r)`.
125 ///
126 /// An alternative pattern is possible: `fn foo<R: Rng>(rng: R)`. This has some
127 /// trade-offs. It allows the argument to be consumed directly without a `&mut`
128 /// (which is how `from_rng(thread_rng())` works); also it still works directly
129 /// on references (including type-erased references). Unfortunately within the
130 /// function `foo` it is not known whether `rng` is a reference type or not,
131 /// hence many uses of `rng` require an extra reference, either explicitly
132 /// (`distr.sample(&mut rng)`) or implicitly (`rng.gen()`); one may hope the
133 /// optimiser can remove redundant references later.
134 ///
135 /// Example:
136 ///
137 /// ```
138 /// # use rand::thread_rng;
139 /// use rand::Rng;
140 ///
141 /// fn foo<R: Rng + ?Sized>(rng: &mut R) -> f32 {
142 ///     rng.gen()
143 /// }
144 ///
145 /// # let v = foo(&mut thread_rng());
146 /// ```
147 pub trait Rng: RngCore {
148     /// Return a random value supporting the [`Standard`] distribution.
149     ///
150     /// # Example
151     ///
152     /// ```
153     /// use rand::{thread_rng, Rng};
154     ///
155     /// let mut rng = thread_rng();
156     /// let x: u32 = rng.gen();
157     /// println!("{}", x);
158     /// println!("{:?}", rng.gen::<(f64, bool)>());
159     /// ```
160     ///
161     /// # Arrays and tuples
162     ///
163     /// The `rng.gen()` method is able to generate arrays (up to 32 elements)
164     /// and tuples (up to 12 elements), so long as all element types can be
165     /// generated.
166     ///
167     /// For arrays of integers, especially for those with small element types
168     /// (< 64 bit), it will likely be faster to instead use [`Rng::fill`].
169     ///
170     /// ```
171     /// use rand::{thread_rng, Rng};
172     ///
173     /// let mut rng = thread_rng();
174     /// let tuple: (u8, i32, char) = rng.gen(); // arbitrary tuple support
175     ///
176     /// let arr1: [f32; 32] = rng.gen();        // array construction
177     /// let mut arr2 = [0u8; 128];
178     /// rng.fill(&mut arr2);                    // array fill
179     /// ```
180     ///
181     /// [`Standard`]: distributions::Standard
182     #[inline]
gen<T>(&mut self) -> T where Standard: Distribution<T>183     fn gen<T>(&mut self) -> T
184     where Standard: Distribution<T> {
185         Standard.sample(self)
186     }
187 
188     /// Generate a random value in the range [`low`, `high`), i.e. inclusive of
189     /// `low` and exclusive of `high`.
190     ///
191     /// This function is optimised for the case that only a single sample is
192     /// made from the given range. See also the [`Uniform`] distribution
193     /// type which may be faster if sampling from the same range repeatedly.
194     ///
195     /// # Panics
196     ///
197     /// Panics if `low >= high`.
198     ///
199     /// # Example
200     ///
201     /// ```
202     /// use rand::{thread_rng, Rng};
203     ///
204     /// let mut rng = thread_rng();
205     /// let n: u32 = rng.gen_range(0, 10);
206     /// println!("{}", n);
207     /// let m: f64 = rng.gen_range(-40.0f64, 1.3e5f64);
208     /// println!("{}", m);
209     /// ```
210     ///
211     /// [`Uniform`]: distributions::uniform::Uniform
gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T where B1: SampleBorrow<T> + Sized, B2: SampleBorrow<T> + Sized,212     fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T
213     where
214         B1: SampleBorrow<T> + Sized,
215         B2: SampleBorrow<T> + Sized,
216     {
217         T::Sampler::sample_single(low, high, self)
218     }
219 
220     /// Sample a new value, using the given distribution.
221     ///
222     /// ### Example
223     ///
224     /// ```
225     /// use rand::{thread_rng, Rng};
226     /// use rand::distributions::Uniform;
227     ///
228     /// let mut rng = thread_rng();
229     /// let x = rng.sample(Uniform::new(10u32, 15));
230     /// // Type annotation requires two types, the type and distribution; the
231     /// // distribution can be inferred.
232     /// let y = rng.sample::<u16, _>(Uniform::new(10, 15));
233     /// ```
sample<T, D: Distribution<T>>(&mut self, distr: D) -> T234     fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T {
235         distr.sample(self)
236     }
237 
238     /// Create an iterator that generates values using the given distribution.
239     ///
240     /// Note that this function takes its arguments by value. This works since
241     /// `(&mut R): Rng where R: Rng` and
242     /// `(&D): Distribution where D: Distribution`,
243     /// however borrowing is not automatic hence `rng.sample_iter(...)` may
244     /// need to be replaced with `(&mut rng).sample_iter(...)`.
245     ///
246     /// # Example
247     ///
248     /// ```
249     /// use rand::{thread_rng, Rng};
250     /// use rand::distributions::{Alphanumeric, Uniform, Standard};
251     ///
252     /// let rng = thread_rng();
253     ///
254     /// // Vec of 16 x f32:
255     /// let v: Vec<f32> = rng.sample_iter(Standard).take(16).collect();
256     ///
257     /// // String:
258     /// let s: String = rng.sample_iter(Alphanumeric).take(7).collect();
259     ///
260     /// // Combined values
261     /// println!("{:?}", rng.sample_iter(Standard).take(5)
262     ///                              .collect::<Vec<(f64, bool)>>());
263     ///
264     /// // Dice-rolling:
265     /// let die_range = Uniform::new_inclusive(1, 6);
266     /// let mut roll_die = rng.sample_iter(die_range);
267     /// while roll_die.next().unwrap() != 6 {
268     ///     println!("Not a 6; rolling again!");
269     /// }
270     /// ```
sample_iter<T, D>(self, distr: D) -> distributions::DistIter<D, Self, T> where D: Distribution<T>, Self: Sized,271     fn sample_iter<T, D>(self, distr: D) -> distributions::DistIter<D, Self, T>
272     where
273         D: Distribution<T>,
274         Self: Sized,
275     {
276         distr.sample_iter(self)
277     }
278 
279     /// Fill `dest` entirely with random bytes (uniform value distribution),
280     /// where `dest` is any type supporting [`AsByteSliceMut`], namely slices
281     /// and arrays over primitive integer types (`i8`, `i16`, `u32`, etc.).
282     ///
283     /// On big-endian platforms this performs byte-swapping to ensure
284     /// portability of results from reproducible generators.
285     ///
286     /// This uses [`fill_bytes`] internally which may handle some RNG errors
287     /// implicitly (e.g. waiting if the OS generator is not ready), but panics
288     /// on other errors. See also [`try_fill`] which returns errors.
289     ///
290     /// # Example
291     ///
292     /// ```
293     /// use rand::{thread_rng, Rng};
294     ///
295     /// let mut arr = [0i8; 20];
296     /// thread_rng().fill(&mut arr[..]);
297     /// ```
298     ///
299     /// [`fill_bytes`]: RngCore::fill_bytes
300     /// [`try_fill`]: Rng::try_fill
fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T)301     fn fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T) {
302         self.fill_bytes(dest.as_byte_slice_mut());
303         dest.to_le();
304     }
305 
306     /// Fill `dest` entirely with random bytes (uniform value distribution),
307     /// where `dest` is any type supporting [`AsByteSliceMut`], namely slices
308     /// and arrays over primitive integer types (`i8`, `i16`, `u32`, etc.).
309     ///
310     /// On big-endian platforms this performs byte-swapping to ensure
311     /// portability of results from reproducible generators.
312     ///
313     /// This is identical to [`fill`] except that it uses [`try_fill_bytes`]
314     /// internally and forwards RNG errors.
315     ///
316     /// # Example
317     ///
318     /// ```
319     /// # use rand::Error;
320     /// use rand::{thread_rng, Rng};
321     ///
322     /// # fn try_inner() -> Result<(), Error> {
323     /// let mut arr = [0u64; 4];
324     /// thread_rng().try_fill(&mut arr[..])?;
325     /// # Ok(())
326     /// # }
327     ///
328     /// # try_inner().unwrap()
329     /// ```
330     ///
331     /// [`try_fill_bytes`]: RngCore::try_fill_bytes
332     /// [`fill`]: Rng::fill
try_fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T) -> Result<(), Error>333     fn try_fill<T: AsByteSliceMut + ?Sized>(&mut self, dest: &mut T) -> Result<(), Error> {
334         self.try_fill_bytes(dest.as_byte_slice_mut())?;
335         dest.to_le();
336         Ok(())
337     }
338 
339     /// Return a bool with a probability `p` of being true.
340     ///
341     /// See also the [`Bernoulli`] distribution, which may be faster if
342     /// sampling from the same probability repeatedly.
343     ///
344     /// # Example
345     ///
346     /// ```
347     /// use rand::{thread_rng, Rng};
348     ///
349     /// let mut rng = thread_rng();
350     /// println!("{}", rng.gen_bool(1.0 / 3.0));
351     /// ```
352     ///
353     /// # Panics
354     ///
355     /// If `p < 0` or `p > 1`.
356     ///
357     /// [`Bernoulli`]: distributions::bernoulli::Bernoulli
358     #[inline]
gen_bool(&mut self, p: f64) -> bool359     fn gen_bool(&mut self, p: f64) -> bool {
360         let d = distributions::Bernoulli::new(p).unwrap();
361         self.sample(d)
362     }
363 
364     /// Return a bool with a probability of `numerator/denominator` of being
365     /// true. I.e. `gen_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
366     /// returning true. If `numerator == denominator`, then the returned value
367     /// is guaranteed to be `true`. If `numerator == 0`, then the returned
368     /// value is guaranteed to be `false`.
369     ///
370     /// See also the [`Bernoulli`] distribution, which may be faster if
371     /// sampling from the same `numerator` and `denominator` repeatedly.
372     ///
373     /// # Panics
374     ///
375     /// If `denominator == 0` or `numerator > denominator`.
376     ///
377     /// # Example
378     ///
379     /// ```
380     /// use rand::{thread_rng, Rng};
381     ///
382     /// let mut rng = thread_rng();
383     /// println!("{}", rng.gen_ratio(2, 3));
384     /// ```
385     ///
386     /// [`Bernoulli`]: distributions::bernoulli::Bernoulli
387     #[inline]
gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool388     fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool {
389         let d = distributions::Bernoulli::from_ratio(numerator, denominator).unwrap();
390         self.sample(d)
391     }
392 }
393 
394 impl<R: RngCore + ?Sized> Rng for R {}
395 
396 /// Trait for casting types to byte slices
397 ///
398 /// This is used by the [`Rng::fill`] and [`Rng::try_fill`] methods.
399 pub trait AsByteSliceMut {
400     /// Return a mutable reference to self as a byte slice
as_byte_slice_mut(&mut self) -> &mut [u8]401     fn as_byte_slice_mut(&mut self) -> &mut [u8];
402 
403     /// Call `to_le` on each element (i.e. byte-swap on Big Endian platforms).
to_le(&mut self)404     fn to_le(&mut self);
405 }
406 
407 impl AsByteSliceMut for [u8] {
as_byte_slice_mut(&mut self) -> &mut [u8]408     fn as_byte_slice_mut(&mut self) -> &mut [u8] {
409         self
410     }
411 
to_le(&mut self)412     fn to_le(&mut self) {}
413 }
414 
415 macro_rules! impl_as_byte_slice {
416     () => {};
417     ($t:ty) => {
418         impl AsByteSliceMut for [$t] {
419             fn as_byte_slice_mut(&mut self) -> &mut [u8] {
420                 if self.len() == 0 {
421                     unsafe {
422                         // must not use null pointer
423                         slice::from_raw_parts_mut(0x1 as *mut u8, 0)
424                     }
425                 } else {
426                     unsafe {
427                         slice::from_raw_parts_mut(self.as_mut_ptr()
428                             as *mut u8,
429                             self.len() * mem::size_of::<$t>()
430                         )
431                     }
432                 }
433             }
434 
435             fn to_le(&mut self) {
436                 for x in self {
437                     *x = x.to_le();
438                 }
439             }
440         }
441 
442         impl AsByteSliceMut for [Wrapping<$t>] {
443             fn as_byte_slice_mut(&mut self) -> &mut [u8] {
444                 if self.len() == 0 {
445                     unsafe {
446                         // must not use null pointer
447                         slice::from_raw_parts_mut(0x1 as *mut u8, 0)
448                     }
449                 } else {
450                     unsafe {
451                         slice::from_raw_parts_mut(self.as_mut_ptr()
452                             as *mut u8,
453                             self.len() * mem::size_of::<$t>()
454                         )
455                     }
456                 }
457             }
458 
459             fn to_le(&mut self) {
460                 for x in self {
461                     *x = Wrapping(x.0.to_le());
462                 }
463             }
464         }
465     };
466     ($t:ty, $($tt:ty,)*) => {
467         impl_as_byte_slice!($t);
468         // TODO: this could replace above impl once Rust #32463 is fixed
469         // impl_as_byte_slice!(Wrapping<$t>);
470         impl_as_byte_slice!($($tt,)*);
471     }
472 }
473 
474 impl_as_byte_slice!(u16, u32, u64, usize,);
475 #[cfg(not(target_os = "emscripten"))]
476 impl_as_byte_slice!(u128);
477 impl_as_byte_slice!(i8, i16, i32, i64, isize,);
478 #[cfg(not(target_os = "emscripten"))]
479 impl_as_byte_slice!(i128);
480 
481 macro_rules! impl_as_byte_slice_arrays {
482     ($n:expr,) => {};
483     ($n:expr, $N:ident) => {
484         impl<T> AsByteSliceMut for [T; $n] where [T]: AsByteSliceMut {
485             fn as_byte_slice_mut(&mut self) -> &mut [u8] {
486                 self[..].as_byte_slice_mut()
487             }
488 
489             fn to_le(&mut self) {
490                 self[..].to_le()
491             }
492         }
493     };
494     ($n:expr, $N:ident, $($NN:ident,)*) => {
495         impl_as_byte_slice_arrays!($n, $N);
496         impl_as_byte_slice_arrays!($n - 1, $($NN,)*);
497     };
498     (!div $n:expr,) => {};
499     (!div $n:expr, $N:ident, $($NN:ident,)*) => {
500         impl_as_byte_slice_arrays!($n, $N);
501         impl_as_byte_slice_arrays!(!div $n / 2, $($NN,)*);
502     };
503 }
504 #[rustfmt::skip]
505 impl_as_byte_slice_arrays!(32, N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,);
506 impl_as_byte_slice_arrays!(!div 4096, N,N,N,N,N,N,N,);
507 
508 /// Generates a random value using the thread-local random number generator.
509 ///
510 /// This is simply a shortcut for `thread_rng().gen()`. See [`thread_rng`] for
511 /// documentation of the entropy source and [`Standard`] for documentation of
512 /// distributions and type-specific generation.
513 ///
514 /// # Examples
515 ///
516 /// ```
517 /// let x = rand::random::<u8>();
518 /// println!("{}", x);
519 ///
520 /// let y = rand::random::<f64>();
521 /// println!("{}", y);
522 ///
523 /// if rand::random() { // generates a boolean
524 ///     println!("Better lucky than good!");
525 /// }
526 /// ```
527 ///
528 /// If you're calling `random()` in a loop, caching the generator as in the
529 /// following example can increase performance.
530 ///
531 /// ```
532 /// use rand::Rng;
533 ///
534 /// let mut v = vec![1, 2, 3];
535 ///
536 /// for x in v.iter_mut() {
537 ///     *x = rand::random()
538 /// }
539 ///
540 /// // can be made faster by caching thread_rng
541 ///
542 /// let mut rng = rand::thread_rng();
543 ///
544 /// for x in v.iter_mut() {
545 ///     *x = rng.gen();
546 /// }
547 /// ```
548 ///
549 /// [`Standard`]: distributions::Standard
550 #[cfg(feature = "std")]
551 #[inline]
random<T>() -> T where Standard: Distribution<T>552 pub fn random<T>() -> T
553 where Standard: Distribution<T> {
554     thread_rng().gen()
555 }
556 
557 #[cfg(test)]
558 mod test {
559     use super::*;
560     use crate::rngs::mock::StepRng;
561     #[cfg(all(not(feature = "std"), feature = "alloc"))] use alloc::boxed::Box;
562 
563     /// Construct a deterministic RNG with the given seed
rng(seed: u64) -> impl RngCore564     pub fn rng(seed: u64) -> impl RngCore {
565         // For tests, we want a statistically good, fast, reproducible RNG.
566         // PCG32 will do fine, and will be easy to embed if we ever need to.
567         const INC: u64 = 11634580027462260723;
568         rand_pcg::Pcg32::new(seed, INC)
569     }
570 
571     #[test]
test_fill_bytes_default()572     fn test_fill_bytes_default() {
573         let mut r = StepRng::new(0x11_22_33_44_55_66_77_88, 0);
574 
575         // check every remainder mod 8, both in small and big vectors.
576         let lengths = [0, 1, 2, 3, 4, 5, 6, 7, 80, 81, 82, 83, 84, 85, 86, 87];
577         for &n in lengths.iter() {
578             let mut buffer = [0u8; 87];
579             let v = &mut buffer[0..n];
580             r.fill_bytes(v);
581 
582             // use this to get nicer error messages.
583             for (i, &byte) in v.iter().enumerate() {
584                 if byte == 0 {
585                     panic!("byte {} of {} is zero", i, n)
586                 }
587             }
588         }
589     }
590 
591     #[test]
test_fill()592     fn test_fill() {
593         let x = 9041086907909331047; // a random u64
594         let mut rng = StepRng::new(x, 0);
595 
596         // Convert to byte sequence and back to u64; byte-swap twice if BE.
597         let mut array = [0u64; 2];
598         rng.fill(&mut array[..]);
599         assert_eq!(array, [x, x]);
600         assert_eq!(rng.next_u64(), x);
601 
602         // Convert to bytes then u32 in LE order
603         let mut array = [0u32; 2];
604         rng.fill(&mut array[..]);
605         assert_eq!(array, [x as u32, (x >> 32) as u32]);
606         assert_eq!(rng.next_u32(), x as u32);
607 
608         // Check equivalence using wrapped arrays
609         let mut warray = [Wrapping(0u32); 2];
610         rng.fill(&mut warray[..]);
611         assert_eq!(array[0], warray[0].0);
612         assert_eq!(array[1], warray[1].0);
613     }
614 
615     #[test]
test_fill_empty()616     fn test_fill_empty() {
617         let mut array = [0u32; 0];
618         let mut rng = StepRng::new(0, 1);
619         rng.fill(&mut array);
620         rng.fill(&mut array[..]);
621     }
622 
623     #[test]
test_gen_range()624     fn test_gen_range() {
625         let mut r = rng(101);
626         for _ in 0..1000 {
627             let a = r.gen_range(-4711, 17);
628             assert!(a >= -4711 && a < 17);
629             let a = r.gen_range(-3i8, 42);
630             assert!(a >= -3i8 && a < 42i8);
631             let a = r.gen_range(&10u16, 99);
632             assert!(a >= 10u16 && a < 99u16);
633             let a = r.gen_range(-100i32, &2000);
634             assert!(a >= -100i32 && a < 2000i32);
635             let a = r.gen_range(&12u32, &24u32);
636             assert!(a >= 12u32 && a < 24u32);
637 
638             assert_eq!(r.gen_range(0u32, 1), 0u32);
639             assert_eq!(r.gen_range(-12i64, -11), -12i64);
640             assert_eq!(r.gen_range(3_000_000, 3_000_001), 3_000_000);
641         }
642     }
643 
644     #[test]
645     #[should_panic]
test_gen_range_panic_int()646     fn test_gen_range_panic_int() {
647         let mut r = rng(102);
648         r.gen_range(5, -2);
649     }
650 
651     #[test]
652     #[should_panic]
test_gen_range_panic_usize()653     fn test_gen_range_panic_usize() {
654         let mut r = rng(103);
655         r.gen_range(5, 2);
656     }
657 
658     #[test]
test_gen_bool()659     fn test_gen_bool() {
660         let mut r = rng(105);
661         for _ in 0..5 {
662             assert_eq!(r.gen_bool(0.0), false);
663             assert_eq!(r.gen_bool(1.0), true);
664         }
665     }
666 
667     #[test]
test_rng_trait_object()668     fn test_rng_trait_object() {
669         use crate::distributions::{Distribution, Standard};
670         let mut rng = rng(109);
671         let mut r = &mut rng as &mut dyn RngCore;
672         r.next_u32();
673         r.gen::<i32>();
674         assert_eq!(r.gen_range(0, 1), 0);
675         let _c: u8 = Standard.sample(&mut r);
676     }
677 
678     #[test]
679     #[cfg(feature = "alloc")]
test_rng_boxed_trait()680     fn test_rng_boxed_trait() {
681         use crate::distributions::{Distribution, Standard};
682         let rng = rng(110);
683         let mut r = Box::new(rng) as Box<dyn RngCore>;
684         r.next_u32();
685         r.gen::<i32>();
686         assert_eq!(r.gen_range(0, 1), 0);
687         let _c: u8 = Standard.sample(&mut r);
688     }
689 
690     #[test]
691     #[cfg(feature = "std")]
test_random()692     fn test_random() {
693         // not sure how to test this aside from just getting some values
694         let _n: usize = random();
695         let _f: f32 = random();
696         let _o: Option<Option<i8>> = random();
697         let _many: (
698             (),
699             (usize, isize, Option<(u32, (bool,))>),
700             (u8, i8, u16, i16, u32, i32, u64, i64),
701             (f32, (f64, (f64,))),
702         ) = random();
703     }
704 
705     #[test]
706     #[cfg_attr(miri, ignore)] // Miri is too slow
test_gen_ratio_average()707     fn test_gen_ratio_average() {
708         const NUM: u32 = 3;
709         const DENOM: u32 = 10;
710         const N: u32 = 100_000;
711 
712         let mut sum: u32 = 0;
713         let mut rng = rng(111);
714         for _ in 0..N {
715             if rng.gen_ratio(NUM, DENOM) {
716                 sum += 1;
717             }
718         }
719         // Have Binomial(N, NUM/DENOM) distribution
720         let expected = (NUM * N) / DENOM; // exact integer
721         assert!(((sum - expected) as i32).abs() < 500);
722     }
723 }
724