|
36 | 36 | //! |
37 | 37 | //! ## Example |
38 | 38 | //! |
39 | | -//! We demonstrate a simple "step RNG": |
| 39 | +//! We demonstrate a simple multiplicative congruential generator (MCG), taken |
| 40 | +//! from M.E. O'Neill's blog post |
| 41 | +//! [Does It Beat the Minimal Standard?](https://www.pcg-random.org/posts/does-it-beat-the-minimal-standard.html). |
40 | 42 | //! ``` |
41 | 43 | //! use rand_core::{RngCore, SeedableRng, utils}; |
42 | 44 | //! |
43 | | -//! pub struct Step32Rng { |
44 | | -//! state: u32 |
45 | | -//! } |
| 45 | +//! pub struct Mcg128(u128); |
46 | 46 | //! |
47 | | -//! impl SeedableRng for Step32Rng { |
48 | | -//! type Seed = [u8; 4]; |
| 47 | +//! impl SeedableRng for Mcg128 { |
| 48 | +//! type Seed = [u8; 16]; |
49 | 49 | //! |
50 | 50 | //! #[inline] |
51 | 51 | //! fn from_seed(seed: Self::Seed) -> Self { |
52 | 52 | //! // Always use little-endian byte order to ensure portable results |
53 | | -//! let state = u32::from_le_bytes(seed); |
54 | | -//! Self { state } |
| 53 | +//! Self(u128::from_le_bytes(seed)) |
55 | 54 | //! } |
56 | 55 | //! } |
57 | 56 | //! |
58 | | -//! impl RngCore for Step32Rng { |
| 57 | +//! impl RngCore for Mcg128 { |
59 | 58 | //! #[inline] |
60 | 59 | //! fn next_u32(&mut self) -> u32 { |
61 | | -//! let val = self.state; |
62 | | -//! self.state = val + 1; |
63 | | -//! val |
| 60 | +//! self.next_u64() as u32 |
64 | 61 | //! } |
65 | 62 | //! |
66 | 63 | //! #[inline] |
67 | 64 | //! fn next_u64(&mut self) -> u64 { |
68 | | -//! utils::next_u64_via_u32(self) |
| 65 | +//! self.0 = self.0.wrapping_mul(0x0fc94e3bf4e9ab32866458cd56f5e605); |
| 66 | +//! (self.0 >> 64) as u64 |
69 | 67 | //! } |
70 | 68 | //! |
71 | 69 | //! #[inline] |
72 | 70 | //! fn fill_bytes(&mut self, dst: &mut [u8]) { |
73 | | -//! utils::fill_bytes_via_next_word(dst, || self.next_u32()); |
| 71 | +//! utils::fill_bytes_via_next_word(dst, || self.next_u64()); |
74 | 72 | //! } |
75 | 73 | //! } |
76 | | -//! |
77 | | -//! # let mut rng = Step32Rng::seed_from_u64(42); |
78 | | -//! # assert_eq!(rng.next_u32(), 0x7ba1_8fa4); |
79 | | -//! # assert_eq!(rng.next_u64(), 0x7ba1_8fa6_7ba1_8fa5); |
| 74 | +//! # |
| 75 | +//! # let mut rng = Mcg128::seed_from_u64(42); |
| 76 | +//! # assert_eq!(rng.next_u32(), 923954926); |
| 77 | +//! # assert_eq!(rng.next_u64(), 3462997187007721903); |
80 | 78 | //! # let mut buf = [0u8; 5]; |
81 | 79 | //! # rng.fill_bytes(&mut buf); |
82 | | -//! # assert_eq!(buf, [0xa7, 0x8f, 0xa1, 0x7b, 0xa8]); |
| 80 | +//! # assert_eq!(buf, [154, 23, 43, 68, 75]); |
83 | 81 | //! ``` |
84 | 82 |
|
85 | 83 | use crate::RngCore; |
|
0 commit comments