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