rand/lib.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//! 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//! ```
18//! // The prelude import enables methods we use below, specifically
19//! // Rng::random, Rng::sample, SliceRandom::shuffle and IndexedRandom::choose.
20//! use rand::prelude::*;
21//!
22//! // Get an RNG:
23//! let mut rng = rand::rng();
24//!
25//! // Try printing a random unicode code point (probably a bad idea)!
26//! println!("char: '{}'", rng.random::<char>());
27//! // Try printing a random alphanumeric value instead!
28//! println!("alpha: '{}'", rng.sample(rand::distr::Alphanumeric) as char);
29//!
30//! // Generate and shuffle a sequence:
31//! let mut nums: Vec<i32> = (1..100).collect();
32//! nums.shuffle(&mut rng);
33//! // And take a random pick (yes, we didn't need to shuffle first!):
34//! let _ = nums.choose(&mut rng);
35//! ```
36//!
37//! # The Book
38//!
39//! For the user guide and further documentation, please read
40//! [The Rust Rand Book](https://rust-random.github.io/book).
41
42#![doc(
43 html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
44 html_favicon_url = "https://www.rust-lang.org/favicon.ico",
45 html_root_url = "https://rust-random.github.io/rand/"
46)]
47#![deny(missing_docs)]
48#![deny(missing_debug_implementations)]
49#![doc(test(attr(allow(unused_variables), deny(warnings))))]
50#![no_std]
51#![cfg_attr(feature = "simd_support", feature(portable_simd))]
52#![cfg_attr(
53 all(feature = "simd_support", target_feature = "avx512bw"),
54 feature(stdarch_x86_avx512)
55)]
56#![cfg_attr(docsrs, feature(doc_auto_cfg))]
57#![allow(
58 clippy::float_cmp,
59 clippy::neg_cmp_op_on_partial_ord,
60 clippy::nonminimal_bool
61)]
62
63#[cfg(feature = "alloc")]
64extern crate alloc;
65#[cfg(feature = "std")]
66extern crate std;
67
68#[allow(unused)]
69macro_rules! trace { ($($x:tt)*) => (
70 #[cfg(feature = "log")] {
71 log::trace!($($x)*)
72 }
73) }
74#[allow(unused)]
75macro_rules! debug { ($($x:tt)*) => (
76 #[cfg(feature = "log")] {
77 log::debug!($($x)*)
78 }
79) }
80#[allow(unused)]
81macro_rules! info { ($($x:tt)*) => (
82 #[cfg(feature = "log")] {
83 log::info!($($x)*)
84 }
85) }
86#[allow(unused)]
87macro_rules! warn { ($($x:tt)*) => (
88 #[cfg(feature = "log")] {
89 log::warn!($($x)*)
90 }
91) }
92#[allow(unused)]
93macro_rules! error { ($($x:tt)*) => (
94 #[cfg(feature = "log")] {
95 log::error!($($x)*)
96 }
97) }
98
99// Re-exports from rand_core
100pub use rand_core::{CryptoRng, RngCore, SeedableRng, TryCryptoRng, TryRngCore};
101
102// Public modules
103pub mod distr;
104pub mod prelude;
105mod rng;
106pub mod rngs;
107pub mod seq;
108
109// Public exports
110#[cfg(feature = "thread_rng")]
111pub use crate::rngs::thread::rng;
112
113/// Access the thread-local generator
114///
115/// Use [`rand::rng()`](rng()) instead.
116#[cfg(feature = "thread_rng")]
117#[deprecated(since = "0.9.0", note = "renamed to `rng`")]
118#[inline]
119pub fn thread_rng() -> crate::rngs::ThreadRng {
120 rng()
121}
122
123pub use rng::{Fill, Rng};
124
125#[cfg(feature = "thread_rng")]
126use crate::distr::{Distribution, StandardUniform};
127
128/// Generate a random value using the thread-local random number generator.
129///
130/// This function is shorthand for <code>[rng()].[random()](Rng::random)</code>:
131///
132/// - See [`ThreadRng`] for documentation of the generator and security
133/// - See [`StandardUniform`] for documentation of supported types and distributions
134///
135/// # Examples
136///
137/// ```
138/// let x = rand::random::<u8>();
139/// println!("{}", x);
140///
141/// let y = rand::random::<f64>();
142/// println!("{}", y);
143///
144/// if rand::random() { // generates a boolean
145/// println!("Better lucky than good!");
146/// }
147/// ```
148///
149/// If you're calling `random()` repeatedly, consider using a local `rng`
150/// handle to save an initialization-check on each usage:
151///
152/// ```
153/// use rand::Rng; // provides the `random` method
154///
155/// let mut rng = rand::rng(); // a local handle to the generator
156///
157/// let mut v = vec![1, 2, 3];
158///
159/// for x in v.iter_mut() {
160/// *x = rng.random();
161/// }
162/// ```
163///
164/// [`StandardUniform`]: distr::StandardUniform
165/// [`ThreadRng`]: rngs::ThreadRng
166#[cfg(feature = "thread_rng")]
167#[inline]
168pub fn random<T>() -> T
169where
170 StandardUniform: Distribution<T>,
171{
172 rng().random()
173}
174
175/// Return an iterator over [`random()`] variates
176///
177/// This function is shorthand for
178/// <code>[rng()].[random_iter](Rng::random_iter)()</code>.
179///
180/// # Example
181///
182/// ```
183/// let v: Vec<i32> = rand::random_iter().take(5).collect();
184/// println!("{v:?}");
185/// ```
186#[cfg(feature = "thread_rng")]
187#[inline]
188pub fn random_iter<T>() -> distr::Iter<StandardUniform, rngs::ThreadRng, T>
189where
190 StandardUniform: Distribution<T>,
191{
192 rng().random_iter()
193}
194
195/// Generate a random value in the given range using the thread-local random number generator.
196///
197/// This function is shorthand for
198/// <code>[rng()].[random_range](Rng::random_range)(<var>range</var>)</code>.
199///
200/// # Example
201///
202/// ```
203/// let y: f32 = rand::random_range(0.0..=1e9);
204/// println!("{}", y);
205///
206/// let words: Vec<&str> = "Mary had a little lamb".split(' ').collect();
207/// println!("{}", words[rand::random_range(..words.len())]);
208/// ```
209/// Note that the first example can also be achieved (without `collect`'ing
210/// to a `Vec`) using [`seq::IteratorRandom::choose`].
211#[cfg(feature = "thread_rng")]
212#[inline]
213pub fn random_range<T, R>(range: R) -> T
214where
215 T: distr::uniform::SampleUniform,
216 R: distr::uniform::SampleRange<T>,
217{
218 rng().random_range(range)
219}
220
221/// Return a bool with a probability `p` of being true.
222///
223/// This function is shorthand for
224/// <code>[rng()].[random_bool](Rng::random_bool)(<var>p</var>)</code>.
225///
226/// # Example
227///
228/// ```
229/// println!("{}", rand::random_bool(1.0 / 3.0));
230/// ```
231///
232/// # Panics
233///
234/// If `p < 0` or `p > 1`.
235#[cfg(feature = "thread_rng")]
236#[inline]
237#[track_caller]
238pub fn random_bool(p: f64) -> bool {
239 rng().random_bool(p)
240}
241
242/// Return a bool with a probability of `numerator/denominator` of being
243/// true.
244///
245/// That is, `random_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
246/// returning true. If `numerator == denominator`, then the returned value
247/// is guaranteed to be `true`. If `numerator == 0`, then the returned
248/// value is guaranteed to be `false`.
249///
250/// See also the [`Bernoulli`] distribution, which may be faster if
251/// sampling from the same `numerator` and `denominator` repeatedly.
252///
253/// This function is shorthand for
254/// <code>[rng()].[random_ratio](Rng::random_ratio)(<var>numerator</var>, <var>denominator</var>)</code>.
255///
256/// # Panics
257///
258/// If `denominator == 0` or `numerator > denominator`.
259///
260/// # Example
261///
262/// ```
263/// println!("{}", rand::random_ratio(2, 3));
264/// ```
265///
266/// [`Bernoulli`]: distr::Bernoulli
267#[cfg(feature = "thread_rng")]
268#[inline]
269#[track_caller]
270pub fn random_ratio(numerator: u32, denominator: u32) -> bool {
271 rng().random_ratio(numerator, denominator)
272}
273
274/// Fill any type implementing [`Fill`] with random data
275///
276/// This function is shorthand for
277/// <code>[rng()].[fill](Rng::fill)(<var>dest</var>)</code>.
278///
279/// # Example
280///
281/// ```
282/// let mut arr = [0i8; 20];
283/// rand::fill(&mut arr[..]);
284/// ```
285///
286/// Note that you can instead use [`random()`] to generate an array of random
287/// data, though this is slower for small elements (smaller than the RNG word
288/// size).
289#[cfg(feature = "thread_rng")]
290#[inline]
291#[track_caller]
292pub fn fill<T: Fill + ?Sized>(dest: &mut T) {
293 dest.fill(&mut rng())
294}
295
296#[cfg(test)]
297mod test {
298 use super::*;
299
300 /// Construct a deterministic RNG with the given seed
301 pub fn rng(seed: u64) -> impl RngCore {
302 // For tests, we want a statistically good, fast, reproducible RNG.
303 // PCG32 will do fine, and will be easy to embed if we ever need to.
304 const INC: u64 = 11634580027462260723;
305 rand_pcg::Pcg32::new(seed, INC)
306 }
307
308 #[test]
309 #[cfg(feature = "thread_rng")]
310 fn test_random() {
311 let _n: u64 = random();
312 let _f: f32 = random();
313 #[allow(clippy::type_complexity)]
314 let _many: (
315 (),
316 [(u32, bool); 3],
317 (u8, i8, u16, i16, u32, i32, u64, i64),
318 (f32, (f64, (f64,))),
319 ) = random();
320 }
321
322 #[test]
323 #[cfg(feature = "thread_rng")]
324 fn test_range() {
325 let _n: usize = random_range(42..=43);
326 let _f: f32 = random_range(42.0..43.0);
327 }
328}