// Copyright 2018 Developers of the Rand project. // Copyright 2013-2017 The Rust Project Developers. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! Utilities for random number generation //! //! Rand provides utilities to generate random numbers, to convert them to //! useful types and distributions, and some randomness-related algorithms. //! //! # Quick Start //! //! To get you started quickly, the easiest and highest-level way to get //! a random value is to use [`random()`]; alternatively you can use //! [`thread_rng()`]. The [`Rng`] trait provides a useful API on all RNGs, while //! the [`distributions`] and [`seq`] modules provide further //! functionality on top of RNGs. //! //! ``` //! use rand::prelude::*; //! //! if rand::random() { // generates a boolean //! // Try printing a random unicode code point (probably a bad idea)! //! println!("char: {}", rand::random::()); //! } //! //! let mut rng = rand::thread_rng(); //! let y: f64 = rng.gen(); // generates a float between 0 and 1 //! //! let mut nums: Vec = (1..100).collect(); //! nums.shuffle(&mut rng); //! ``` //! //! # The Book //! //! For the user guide and further documentation, please read //! [The Rust Rand Book](https://rust-random.github.io/book). #![doc( html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", html_favicon_url = "https://www.rust-lang.org/favicon.ico", html_root_url = "https://rust-random.github.io/rand/" )] #![deny(missing_docs)] #![deny(missing_debug_implementations)] #![doc(test(attr(allow(unused_variables), deny(warnings))))] #![no_std] #![cfg_attr(feature = "simd_support", feature(stdsimd))] #![cfg_attr(doc_cfg, feature(doc_cfg))] #![allow( clippy::float_cmp, clippy::neg_cmp_op_on_partial_ord, )] #[cfg(feature = "std")] extern crate std; #[cfg(feature = "alloc")] extern crate alloc; #[allow(unused)] macro_rules! trace { ($($x:tt)*) => ( #[cfg(feature = "log")] { log::trace!($($x)*) } ) } #[allow(unused)] macro_rules! debug { ($($x:tt)*) => ( #[cfg(feature = "log")] { log::debug!($($x)*) } ) } #[allow(unused)] macro_rules! info { ($($x:tt)*) => ( #[cfg(feature = "log")] { log::info!($($x)*) } ) } #[allow(unused)] macro_rules! warn { ($($x:tt)*) => ( #[cfg(feature = "log")] { log::warn!($($x)*) } ) } #[allow(unused)] macro_rules! error { ($($x:tt)*) => ( #[cfg(feature = "log")] { log::error!($($x)*) } ) } // Re-exports from rand_core pub use rand_core::{CryptoRng, Error, RngCore, SeedableRng}; // Public modules pub mod distributions; pub mod prelude; mod rng; pub mod rngs; pub mod seq; // Public exports #[cfg(all(feature = "std", feature = "std_rng"))] pub use crate::rngs::thread::thread_rng; pub use rng::{Fill, Rng}; #[cfg(all(feature = "std", feature = "std_rng"))] use crate::distributions::{Distribution, Standard}; /// Generates a random value using the thread-local random number generator. /// /// This is simply a shortcut for `thread_rng().gen()`. See [`thread_rng`] for /// documentation of the entropy source and [`Standard`] for documentation of /// distributions and type-specific generation. /// /// # Provided implementations /// /// The following types have provided implementations that /// generate values with the following ranges and distributions: /// /// * Integers (`i32`, `u32`, `isize`, `usize`, etc.): Uniformly distributed /// over all values of the type. /// * `char`: Uniformly distributed over all Unicode scalar values, i.e. all /// code points in the range `0...0x10_FFFF`, except for the range /// `0xD800...0xDFFF` (the surrogate code points). This includes /// unassigned/reserved code points. /// * `bool`: Generates `false` or `true`, each with probability 0.5. /// * Floating point types (`f32` and `f64`): Uniformly distributed in the /// half-open range `[0, 1)`. See notes below. /// * Wrapping integers (`Wrapping`), besides the type identical to their /// normal integer variants. /// /// Also supported is the generation of the following /// compound types where all component types are supported: /// /// * Tuples (up to 12 elements): each element is generated sequentially. /// * Arrays (up to 32 elements): each element is generated sequentially; /// see also [`Rng::fill`] which supports arbitrary array length for integer /// types and tends to be faster for `u32` and smaller types. /// * `Option` first generates a `bool`, and if true generates and returns /// `Some(value)` where `value: T`, otherwise returning `None`. /// /// # Examples /// /// ``` /// let x = rand::random::(); /// println!("{}", x); /// /// let y = rand::random::(); /// println!("{}", y); /// /// if rand::random() { // generates a boolean /// println!("Better lucky than good!"); /// } /// ``` /// /// If you're calling `random()` in a loop, caching the generator as in the /// following example can increase performance. /// /// ``` /// use rand::Rng; /// /// let mut v = vec![1, 2, 3]; /// /// for x in v.iter_mut() { /// *x = rand::random() /// } /// /// // can be made faster by caching thread_rng /// /// let mut rng = rand::thread_rng(); /// /// for x in v.iter_mut() { /// *x = rng.gen(); /// } /// ``` /// /// [`Standard`]: distributions::Standard #[cfg(all(feature = "std", feature = "std_rng"))] #[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", feature = "std_rng"))))] #[inline] pub fn random() -> T where Standard: Distribution { thread_rng().gen() } #[cfg(test)] mod test { use super::*; /// Construct a deterministic RNG with the given seed pub fn rng(seed: u64) -> impl RngCore { // For tests, we want a statistically good, fast, reproducible RNG. // PCG32 will do fine, and will be easy to embed if we ever need to. const INC: u64 = 11634580027462260723; rand_pcg::Pcg32::new(seed, INC) } #[test] #[cfg(all(feature = "std", feature = "std_rng"))] fn test_random() { let _n: usize = random(); let _f: f32 = random(); let _o: Option> = random(); #[allow(clippy::type_complexity)] let _many: ( (), (usize, isize, Option<(u32, (bool,))>), (u8, i8, u16, i16, u32, i32, u64, i64), (f32, (f64, (f64,))), ) = random(); } }