Skip to main content

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_cfg))]
57#![allow(
58    clippy::float_cmp,
59    clippy::neg_cmp_op_on_partial_ord,
60    clippy::nonminimal_bool
61)]
62#![deny(clippy::undocumented_unsafe_blocks)]
63
64#[cfg(feature = "alloc")]
65extern crate alloc;
66#[cfg(feature = "std")]
67extern crate std;
68
69// Re-export rand_core itself
70pub use rand_core;
71
72// Re-exports from rand_core
73pub use rand_core::{CryptoRng, RngCore, SeedableRng, TryCryptoRng, TryRngCore};
74
75// Public modules
76pub mod distr;
77pub mod prelude;
78mod rng;
79pub mod rngs;
80pub mod seq;
81
82// Public exports
83#[cfg(feature = "thread_rng")]
84pub use crate::rngs::thread::rng;
85
86/// Access the thread-local generator
87///
88/// Use [`rand::rng()`](rng()) instead.
89#[cfg(feature = "thread_rng")]
90#[deprecated(since = "0.9.0", note = "Renamed to `rng`")]
91#[inline]
92pub fn thread_rng() -> crate::rngs::ThreadRng {
93    rng()
94}
95
96pub use rng::{Fill, Rng};
97
98#[cfg(feature = "thread_rng")]
99use crate::distr::{Distribution, StandardUniform};
100
101/// Generate a random value using the thread-local random number generator.
102///
103/// This function is shorthand for <code>[rng()].[random()](Rng::random)</code>:
104///
105/// -   See [`ThreadRng`] for documentation of the generator and security
106/// -   See [`StandardUniform`] for documentation of supported types and distributions
107///
108/// # Examples
109///
110/// ```
111/// let x = rand::random::<u8>();
112/// println!("{}", x);
113///
114/// let y = rand::random::<f64>();
115/// println!("{}", y);
116///
117/// if rand::random() { // generates a boolean
118///     println!("Better lucky than good!");
119/// }
120/// ```
121///
122/// If you're calling `random()` repeatedly, consider using a local `rng`
123/// handle to save an initialization-check on each usage:
124///
125/// ```
126/// use rand::Rng; // provides the `random` method
127///
128/// let mut rng = rand::rng(); // a local handle to the generator
129///
130/// let mut v = vec![1, 2, 3];
131///
132/// for x in v.iter_mut() {
133///     *x = rng.random();
134/// }
135/// ```
136///
137/// [`StandardUniform`]: distr::StandardUniform
138/// [`ThreadRng`]: rngs::ThreadRng
139#[cfg(feature = "thread_rng")]
140#[inline]
141pub fn random<T>() -> T
142where
143    StandardUniform: Distribution<T>,
144{
145    rng().random()
146}
147
148/// Return an iterator over [`random()`] variates
149///
150/// This function is shorthand for
151/// <code>[rng()].[random_iter](Rng::random_iter)()</code>.
152///
153/// # Example
154///
155/// ```
156/// let v: Vec<i32> = rand::random_iter().take(5).collect();
157/// println!("{v:?}");
158/// ```
159#[cfg(feature = "thread_rng")]
160#[inline]
161pub fn random_iter<T>() -> distr::Iter<StandardUniform, rngs::ThreadRng, T>
162where
163    StandardUniform: Distribution<T>,
164{
165    rng().random_iter()
166}
167
168/// Generate a random value in the given range using the thread-local random number generator.
169///
170/// This function is shorthand for
171/// <code>[rng()].[random_range](Rng::random_range)(<var>range</var>)</code>.
172///
173/// # Example
174///
175/// ```
176/// let y: f32 = rand::random_range(0.0..=1e9);
177/// println!("{}", y);
178///
179/// let words: Vec<&str> = "Mary had a little lamb".split(' ').collect();
180/// println!("{}", words[rand::random_range(..words.len())]);
181/// ```
182/// Note that the first example can also be achieved (without `collect`'ing
183/// to a `Vec`) using [`seq::IteratorRandom::choose`].
184#[cfg(feature = "thread_rng")]
185#[inline]
186pub fn random_range<T, R>(range: R) -> T
187where
188    T: distr::uniform::SampleUniform,
189    R: distr::uniform::SampleRange<T>,
190{
191    rng().random_range(range)
192}
193
194/// Return a bool with a probability `p` of being true.
195///
196/// This function is shorthand for
197/// <code>[rng()].[random_bool](Rng::random_bool)(<var>p</var>)</code>.
198///
199/// # Example
200///
201/// ```
202/// println!("{}", rand::random_bool(1.0 / 3.0));
203/// ```
204///
205/// # Panics
206///
207/// If `p < 0` or `p > 1`.
208#[cfg(feature = "thread_rng")]
209#[inline]
210#[track_caller]
211pub fn random_bool(p: f64) -> bool {
212    rng().random_bool(p)
213}
214
215/// Return a bool with a probability of `numerator/denominator` of being
216/// true.
217///
218/// That is, `random_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
219/// returning true. If `numerator == denominator`, then the returned value
220/// is guaranteed to be `true`. If `numerator == 0`, then the returned
221/// value is guaranteed to be `false`.
222///
223/// See also the [`Bernoulli`] distribution, which may be faster if
224/// sampling from the same `numerator` and `denominator` repeatedly.
225///
226/// This function is shorthand for
227/// <code>[rng()].[random_ratio](Rng::random_ratio)(<var>numerator</var>, <var>denominator</var>)</code>.
228///
229/// # Panics
230///
231/// If `denominator == 0` or `numerator > denominator`.
232///
233/// # Example
234///
235/// ```
236/// println!("{}", rand::random_ratio(2, 3));
237/// ```
238///
239/// [`Bernoulli`]: distr::Bernoulli
240#[cfg(feature = "thread_rng")]
241#[inline]
242#[track_caller]
243pub fn random_ratio(numerator: u32, denominator: u32) -> bool {
244    rng().random_ratio(numerator, denominator)
245}
246
247/// Fill any type implementing [`Fill`] with random data
248///
249/// This function is shorthand for
250/// <code>[rng()].[fill](Rng::fill)(<var>dest</var>)</code>.
251///
252/// # Example
253///
254/// ```
255/// let mut arr = [0i8; 20];
256/// rand::fill(&mut arr[..]);
257/// ```
258///
259/// Note that you can instead use [`random()`] to generate an array of random
260/// data, though this is slower for small elements (smaller than the RNG word
261/// size).
262#[cfg(feature = "thread_rng")]
263#[inline]
264#[track_caller]
265pub fn fill<T: Fill + ?Sized>(dest: &mut T) {
266    dest.fill(&mut rng())
267}
268
269#[cfg(test)]
270mod test {
271    use super::*;
272
273    /// Construct a deterministic RNG with the given seed
274    pub fn rng(seed: u64) -> impl RngCore {
275        // For tests, we want a statistically good, fast, reproducible RNG.
276        // PCG32 will do fine, and will be easy to embed if we ever need to.
277        const INC: u64 = 11634580027462260723;
278        rand_pcg::Pcg32::new(seed, INC)
279    }
280
281    /// Construct a generator yielding a constant value
282    pub fn const_rng(x: u64) -> StepRng {
283        StepRng(x, 0)
284    }
285
286    /// Construct a generator yielding an arithmetic sequence
287    pub fn step_rng(x: u64, increment: u64) -> StepRng {
288        StepRng(x, increment)
289    }
290
291    #[derive(Clone)]
292    pub struct StepRng(u64, u64);
293    impl RngCore for StepRng {
294        fn next_u32(&mut self) -> u32 {
295            self.next_u64() as u32
296        }
297
298        fn next_u64(&mut self) -> u64 {
299            let res = self.0;
300            self.0 = self.0.wrapping_add(self.1);
301            res
302        }
303
304        fn fill_bytes(&mut self, dst: &mut [u8]) {
305            rand_core::impls::fill_bytes_via_next(self, dst)
306        }
307    }
308
309    #[test]
310    #[cfg(feature = "thread_rng")]
311    fn test_random() {
312        let _n: u64 = random();
313        let _f: f32 = random();
314        #[allow(clippy::type_complexity)]
315        let _many: (
316            (),
317            [(u32, bool); 3],
318            (u8, i8, u16, i16, u32, i32, u64, i64),
319            (f32, (f64, (f64,))),
320        ) = random();
321    }
322
323    #[test]
324    #[cfg(feature = "thread_rng")]
325    fn test_range() {
326        let _n: usize = random_range(42..=43);
327        let _f: f32 = random_range(42.0..43.0);
328    }
329}