]>
Commit | Line | Data |
---|---|---|
0731742a XL |
1 | // Copyright 2018 Developers of the Rand project. |
2 | // Copyright 2013-2017 The Rust Project Developers. | |
b7449926 XL |
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 | //! | |
0731742a | 15 | //! # Quick Start |
416331ca | 16 | //! |
b7449926 | 17 | //! To get you started quickly, the easiest and highest-level way to get |
0731742a XL |
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 | |
416331ca | 20 | //! the [`distributions`] and [`seq`] modules provide further |
0731742a | 21 | //! functionality on top of RNGs. |
b7449926 XL |
22 | //! |
23 | //! ``` | |
0731742a | 24 | //! use rand::prelude::*; |
416331ca | 25 | //! |
b7449926 | 26 | //! if rand::random() { // generates a boolean |
0731742a XL |
27 | //! // Try printing a random unicode code point (probably a bad idea)! |
28 | //! println!("char: {}", rand::random::<char>()); | |
b7449926 | 29 | //! } |
b7449926 | 30 | //! |
0731742a XL |
31 | //! let mut rng = rand::thread_rng(); |
32 | //! let y: f64 = rng.gen(); // generates a float between 0 and 1 | |
b7449926 | 33 | //! |
0731742a XL |
34 | //! let mut nums: Vec<i32> = (1..100).collect(); |
35 | //! nums.shuffle(&mut rng); | |
b7449926 | 36 | //! ``` |
b7449926 | 37 | //! |
0731742a | 38 | //! # The Book |
416331ca | 39 | //! |
0731742a XL |
40 | //! For the user guide and futher documentation, please read |
41 | //! [The Rust Rand Book](https://rust-random.github.io/book). | |
b7449926 | 42 | |
dfeec247 XL |
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 | )] | |
b7449926 XL |
48 | #![deny(missing_docs)] |
49 | #![deny(missing_debug_implementations)] | |
50 | #![doc(test(attr(allow(unused_variables), deny(warnings))))] | |
dfeec247 XL |
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 | )] | |
b7449926 | 58 | |
dfeec247 | 59 | #[cfg(all(feature = "alloc", not(feature = "std")))] extern crate alloc; |
b7449926 | 60 | |
b7449926 | 61 | #[allow(unused)] |
416331ca XL |
62 | macro_rules! trace { ($($x:tt)*) => ( |
63 | #[cfg(feature = "log")] { | |
64 | log::trace!($($x)*) | |
65 | } | |
66 | ) } | |
b7449926 | 67 | #[allow(unused)] |
416331ca XL |
68 | macro_rules! debug { ($($x:tt)*) => ( |
69 | #[cfg(feature = "log")] { | |
70 | log::debug!($($x)*) | |
71 | } | |
72 | ) } | |
b7449926 | 73 | #[allow(unused)] |
416331ca XL |
74 | macro_rules! info { ($($x:tt)*) => ( |
75 | #[cfg(feature = "log")] { | |
76 | log::info!($($x)*) | |
77 | } | |
78 | ) } | |
b7449926 | 79 | #[allow(unused)] |
416331ca XL |
80 | macro_rules! warn { ($($x:tt)*) => ( |
81 | #[cfg(feature = "log")] { | |
82 | log::warn!($($x)*) | |
83 | } | |
84 | ) } | |
b7449926 | 85 | #[allow(unused)] |
416331ca XL |
86 | macro_rules! error { ($($x:tt)*) => ( |
87 | #[cfg(feature = "log")] { | |
88 | log::error!($($x)*) | |
89 | } | |
90 | ) } | |
b7449926 XL |
91 | |
92 | // Re-exports from rand_core | |
dfeec247 | 93 | pub use rand_core::{CryptoRng, Error, RngCore, SeedableRng}; |
b7449926 XL |
94 | |
95 | // Public exports | |
dfeec247 | 96 | #[cfg(feature = "std")] pub use crate::rngs::thread::thread_rng; |
b7449926 XL |
97 | |
98 | // Public modules | |
99 | pub mod distributions; | |
100 | pub mod prelude; | |
b7449926 | 101 | pub mod rngs; |
0731742a | 102 | pub mod seq; |
b7449926 | 103 | |
b7449926 | 104 | |
dfeec247 | 105 | use crate::distributions::uniform::{SampleBorrow, SampleUniform, UniformSampler}; |
416331ca | 106 | use crate::distributions::{Distribution, Standard}; |
dfeec247 XL |
107 | use core::num::Wrapping; |
108 | use core::{mem, slice}; | |
b7449926 XL |
109 | |
110 | /// An automatically-implemented extension trait on [`RngCore`] providing high-level | |
111 | /// generic methods for sampling values and other convenience methods. | |
0731742a | 112 | /// |
b7449926 | 113 | /// This is the primary trait to use when generating random values. |
0731742a | 114 | /// |
b7449926 | 115 | /// # Generic usage |
0731742a | 116 | /// |
b7449926 XL |
117 | /// The basic pattern is `fn foo<R: Rng + ?Sized>(rng: &mut R)`. Some |
118 | /// things are worth noting here: | |
0731742a | 119 | /// |
b7449926 XL |
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)`. | |
0731742a | 125 | /// |
b7449926 XL |
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. | |
0731742a | 134 | /// |
b7449926 | 135 | /// Example: |
0731742a | 136 | /// |
b7449926 XL |
137 | /// ``` |
138 | /// # use rand::thread_rng; | |
139 | /// use rand::Rng; | |
0731742a | 140 | /// |
b7449926 XL |
141 | /// fn foo<R: Rng + ?Sized>(rng: &mut R) -> f32 { |
142 | /// rng.gen() | |
143 | /// } | |
144 | /// | |
145 | /// # let v = foo(&mut thread_rng()); | |
146 | /// ``` | |
b7449926 XL |
147 | pub trait Rng: RngCore { |
148 | /// Return a random value supporting the [`Standard`] distribution. | |
149 | /// | |
b7449926 XL |
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 | /// ``` | |
416331ca XL |
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 | |
b7449926 | 182 | #[inline] |
416331ca XL |
183 | fn gen<T>(&mut self) -> T |
184 | where Standard: Distribution<T> { | |
b7449926 XL |
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 | /// | |
416331ca | 211 | /// [`Uniform`]: distributions::uniform::Uniform |
0731742a | 212 | fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T |
416331ca XL |
213 | where |
214 | B1: SampleBorrow<T> + Sized, | |
215 | B2: SampleBorrow<T> + Sized, | |
216 | { | |
b7449926 XL |
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 | /// ``` | |
234 | 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 | /// | |
416331ca XL |
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 | /// | |
b7449926 XL |
246 | /// # Example |
247 | /// | |
248 | /// ``` | |
249 | /// use rand::{thread_rng, Rng}; | |
250 | /// use rand::distributions::{Alphanumeric, Uniform, Standard}; | |
251 | /// | |
416331ca | 252 | /// let rng = thread_rng(); |
b7449926 XL |
253 | /// |
254 | /// // Vec of 16 x f32: | |
416331ca | 255 | /// let v: Vec<f32> = rng.sample_iter(Standard).take(16).collect(); |
b7449926 XL |
256 | /// |
257 | /// // String: | |
416331ca | 258 | /// let s: String = rng.sample_iter(Alphanumeric).take(7).collect(); |
b7449926 XL |
259 | /// |
260 | /// // Combined values | |
416331ca | 261 | /// println!("{:?}", rng.sample_iter(Standard).take(5) |
b7449926 XL |
262 | /// .collect::<Vec<(f64, bool)>>()); |
263 | /// | |
264 | /// // Dice-rolling: | |
265 | /// let die_range = Uniform::new_inclusive(1, 6); | |
416331ca | 266 | /// let mut roll_die = rng.sample_iter(die_range); |
b7449926 XL |
267 | /// while roll_die.next().unwrap() != 6 { |
268 | /// println!("Not a 6; rolling again!"); | |
269 | /// } | |
270 | /// ``` | |
416331ca | 271 | fn sample_iter<T, D>(self, distr: D) -> distributions::DistIter<D, Self, T> |
dfeec247 XL |
272 | where |
273 | D: Distribution<T>, | |
274 | Self: Sized, | |
275 | { | |
b7449926 XL |
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 | /// | |
416331ca XL |
299 | /// [`fill_bytes`]: RngCore::fill_bytes |
300 | /// [`try_fill`]: Rng::try_fill | |
b7449926 XL |
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 | /// | |
416331ca XL |
313 | /// This is identical to [`fill`] except that it uses [`try_fill_bytes`] |
314 | /// internally and forwards RNG errors. | |
b7449926 XL |
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 | /// | |
416331ca XL |
331 | /// [`try_fill_bytes`]: RngCore::try_fill_bytes |
332 | /// [`fill`]: Rng::fill | |
b7449926 XL |
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 | /// | |
0731742a XL |
341 | /// See also the [`Bernoulli`] distribution, which may be faster if |
342 | /// sampling from the same probability repeatedly. | |
b7449926 XL |
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 | /// | |
0731742a | 355 | /// If `p < 0` or `p > 1`. |
b7449926 | 356 | /// |
416331ca | 357 | /// [`Bernoulli`]: distributions::bernoulli::Bernoulli |
b7449926 XL |
358 | #[inline] |
359 | fn gen_bool(&mut self, p: f64) -> bool { | |
416331ca | 360 | let d = distributions::Bernoulli::new(p).unwrap(); |
b7449926 XL |
361 | self.sample(d) |
362 | } | |
363 | ||
0731742a XL |
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`. | |
b7449926 | 369 | /// |
0731742a XL |
370 | /// See also the [`Bernoulli`] distribution, which may be faster if |
371 | /// sampling from the same `numerator` and `denominator` repeatedly. | |
b7449926 | 372 | /// |
0731742a | 373 | /// # Panics |
b7449926 | 374 | /// |
0731742a | 375 | /// If `denominator == 0` or `numerator > denominator`. |
b7449926 XL |
376 | /// |
377 | /// # Example | |
378 | /// | |
379 | /// ``` | |
380 | /// use rand::{thread_rng, Rng}; | |
381 | /// | |
382 | /// let mut rng = thread_rng(); | |
0731742a | 383 | /// println!("{}", rng.gen_ratio(2, 3)); |
b7449926 | 384 | /// ``` |
0731742a | 385 | /// |
416331ca | 386 | /// [`Bernoulli`]: distributions::bernoulli::Bernoulli |
0731742a XL |
387 | #[inline] |
388 | fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool { | |
416331ca | 389 | let d = distributions::Bernoulli::from_ratio(numerator, denominator).unwrap(); |
0731742a | 390 | self.sample(d) |
b7449926 | 391 | } |
b7449926 XL |
392 | } |
393 | ||
394 | impl<R: RngCore + ?Sized> Rng for R {} | |
395 | ||
396 | /// Trait for casting types to byte slices | |
0731742a | 397 | /// |
416331ca | 398 | /// This is used by the [`Rng::fill`] and [`Rng::try_fill`] methods. |
b7449926 XL |
399 | pub trait AsByteSliceMut { |
400 | /// Return a mutable reference to self as a byte slice | |
401 | fn as_byte_slice_mut(&mut self) -> &mut [u8]; | |
0731742a | 402 | |
b7449926 XL |
403 | /// Call `to_le` on each element (i.e. byte-swap on Big Endian platforms). |
404 | fn to_le(&mut self); | |
405 | } | |
406 | ||
407 | impl AsByteSliceMut for [u8] { | |
408 | fn as_byte_slice_mut(&mut self) -> &mut [u8] { | |
409 | self | |
410 | } | |
0731742a | 411 | |
b7449926 XL |
412 | fn to_le(&mut self) {} |
413 | } | |
414 | ||
415 | macro_rules! impl_as_byte_slice { | |
416331ca | 416 | () => {}; |
b7449926 XL |
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 { | |
416331ca | 427 | slice::from_raw_parts_mut(self.as_mut_ptr() |
b7449926 XL |
428 | as *mut u8, |
429 | self.len() * mem::size_of::<$t>() | |
430 | ) | |
431 | } | |
432 | } | |
433 | } | |
0731742a | 434 | |
b7449926 XL |
435 | fn to_le(&mut self) { |
436 | for x in self { | |
437 | *x = x.to_le(); | |
438 | } | |
439 | } | |
440 | } | |
dfeec247 | 441 | |
416331ca XL |
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,)*); | |
b7449926 XL |
471 | } |
472 | } | |
473 | ||
416331ca | 474 | impl_as_byte_slice!(u16, u32, u64, usize,); |
dfeec247 XL |
475 | #[cfg(not(target_os = "emscripten"))] |
476 | impl_as_byte_slice!(u128); | |
416331ca | 477 | impl_as_byte_slice!(i8, i16, i32, i64, isize,); |
dfeec247 XL |
478 | #[cfg(not(target_os = "emscripten"))] |
479 | impl_as_byte_slice!(i128); | |
b7449926 XL |
480 | |
481 | macro_rules! impl_as_byte_slice_arrays { | |
482 | ($n:expr,) => {}; | |
416331ca | 483 | ($n:expr, $N:ident) => { |
b7449926 XL |
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 | }; | |
416331ca XL |
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 | }; | |
b7449926 XL |
498 | (!div $n:expr,) => {}; |
499 | (!div $n:expr, $N:ident, $($NN:ident,)*) => { | |
416331ca | 500 | impl_as_byte_slice_arrays!($n, $N); |
b7449926 | 501 | impl_as_byte_slice_arrays!(!div $n / 2, $($NN,)*); |
b7449926 XL |
502 | }; |
503 | } | |
dfeec247 | 504 | #[rustfmt::skip] |
b7449926 XL |
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 | ||
b7449926 XL |
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 | /// ``` | |
b7449926 XL |
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 | /// | |
416331ca | 549 | /// [`Standard`]: distributions::Standard |
dfeec247 | 550 | #[cfg(feature = "std")] |
b7449926 | 551 | #[inline] |
416331ca XL |
552 | pub fn random<T>() -> T |
553 | where Standard: Distribution<T> { | |
b7449926 XL |
554 | thread_rng().gen() |
555 | } | |
556 | ||
b7449926 XL |
557 | #[cfg(test)] |
558 | mod test { | |
b7449926 | 559 | use super::*; |
dfeec247 XL |
560 | use crate::rngs::mock::StepRng; |
561 | #[cfg(all(not(feature = "std"), feature = "alloc"))] use alloc::boxed::Box; | |
b7449926 | 562 | |
416331ca XL |
563 | /// Construct a deterministic RNG with the given seed |
564 | 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) | |
b7449926 XL |
569 | } |
570 | ||
571 | #[test] | |
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. | |
dfeec247 | 576 | let lengths = [0, 1, 2, 3, 4, 5, 6, 7, 80, 81, 82, 83, 84, 85, 86, 87]; |
b7449926 XL |
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 | } | |
0731742a | 590 | |
b7449926 XL |
591 | #[test] |
592 | fn test_fill() { | |
dfeec247 | 593 | let x = 9041086907909331047; // a random u64 |
b7449926 | 594 | let mut rng = StepRng::new(x, 0); |
0731742a | 595 | |
b7449926 XL |
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); | |
0731742a | 601 | |
b7449926 XL |
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); | |
dfeec247 | 607 | |
416331ca XL |
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); | |
b7449926 | 613 | } |
0731742a | 614 | |
b7449926 XL |
615 | #[test] |
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] | |
624 | fn test_gen_range() { | |
625 | let mut r = rng(101); | |
626 | for _ in 0..1000 { | |
0731742a XL |
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); | |
b7449926 XL |
640 | assert_eq!(r.gen_range(3_000_000, 3_000_001), 3_000_000); |
641 | } | |
b7449926 XL |
642 | } |
643 | ||
644 | #[test] | |
645 | #[should_panic] | |
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] | |
653 | fn test_gen_range_panic_usize() { | |
654 | let mut r = rng(103); | |
655 | r.gen_range(5, 2); | |
656 | } | |
657 | ||
b7449926 XL |
658 | #[test] |
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 | ||
b7449926 XL |
667 | #[test] |
668 | fn test_rng_trait_object() { | |
416331ca | 669 | use crate::distributions::{Distribution, Standard}; |
b7449926 | 670 | let mut rng = rng(109); |
416331ca | 671 | let mut r = &mut rng as &mut dyn RngCore; |
b7449926 XL |
672 | r.next_u32(); |
673 | r.gen::<i32>(); | |
b7449926 XL |
674 | assert_eq!(r.gen_range(0, 1), 0); |
675 | let _c: u8 = Standard.sample(&mut r); | |
676 | } | |
677 | ||
678 | #[test] | |
dfeec247 | 679 | #[cfg(feature = "alloc")] |
b7449926 | 680 | fn test_rng_boxed_trait() { |
416331ca | 681 | use crate::distributions::{Distribution, Standard}; |
b7449926 | 682 | let rng = rng(110); |
416331ca | 683 | let mut r = Box::new(rng) as Box<dyn RngCore>; |
b7449926 XL |
684 | r.next_u32(); |
685 | r.gen::<i32>(); | |
b7449926 XL |
686 | assert_eq!(r.gen_range(0, 1), 0); |
687 | let _c: u8 = Standard.sample(&mut r); | |
688 | } | |
0731742a | 689 | |
b7449926 | 690 | #[test] |
dfeec247 | 691 | #[cfg(feature = "std")] |
b7449926 XL |
692 | fn test_random() { |
693 | // not sure how to test this aside from just getting some values | |
dfeec247 XL |
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(); | |
b7449926 | 703 | } |
0731742a XL |
704 | |
705 | #[test] | |
dfeec247 | 706 | #[cfg_attr(miri, ignore)] // Miri is too slow |
0731742a XL |
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 | |
dfeec247 | 720 | let expected = (NUM * N) / DENOM; // exact integer |
0731742a XL |
721 | assert!(((sum - expected) as i32).abs() < 500); |
722 | } | |
b7449926 | 723 | } |