Coverage Report

Created: 2025-07-02 06:18

/rust/registry/src/index.crates.io-6f17d22bba15001f/rand-0.9.1/src/rng.rs
Line
Count
Source (jump to first uncovered line)
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
12
use crate::distr::uniform::{SampleRange, SampleUniform};
13
use crate::distr::{self, Distribution, StandardUniform};
14
use core::num::Wrapping;
15
use core::{mem, slice};
16
use 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
/// ```
58
pub 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
0
    fn random<T>(&mut self) -> T
96
0
    where
97
0
        StandardUniform: Distribution<T>,
98
0
    {
99
0
        StandardUniform.sample(self)
100
0
    }
Unexecuted instantiation: <rand::rngs::thread::ThreadRng as rand::rng::Rng>::random::<[u8; 5]>
Unexecuted instantiation: <rand::rngs::thread::ThreadRng as rand::rng::Rng>::random::<u8>
Unexecuted instantiation: <rand::rngs::thread::ThreadRng as rand::rng::Rng>::random::<u32>
Unexecuted instantiation: <rand::rngs::thread::ThreadRng as rand::rng::Rng>::random::<u64>
Unexecuted instantiation: <_ as rand::rng::Rng>::random::<_>
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::mock::StepRng, Rng};
114
    ///
115
    /// let rng = StepRng::new(1, 1);
116
    /// let v: Vec<i32> = rng.random_iter().take(5).collect();
117
    /// assert_eq!(&v, &[1, 2, 3, 4, 5]);
118
    /// ```
119
    #[inline]
120
0
    fn random_iter<T>(self) -> distr::Iter<StandardUniform, Self, T>
121
0
    where
122
0
        Self: Sized,
123
0
        StandardUniform: Distribution<T>,
124
0
    {
125
0
        StandardUniform.sample_iter(self)
126
0
    }
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
0
    fn random_range<T, R>(&mut self, range: R) -> T
162
0
    where
163
0
        T: SampleUniform,
164
0
        R: SampleRange<T>,
165
0
    {
166
0
        assert!(!range.is_empty(), "cannot sample empty range");
167
0
        range.sample_single(self).unwrap()
168
0
    }
Unexecuted instantiation: <rand::rngs::thread::ThreadRng as rand::rng::Rng>::random_range::<usize, core::ops::range::RangeInclusive<usize>>
Unexecuted instantiation: <_ as rand::rng::Rng>::random_range::<_, _>
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
0
    fn random_bool(&mut self, p: f64) -> bool {
192
0
        match distr::Bernoulli::new(p) {
193
0
            Ok(d) => self.sample(d),
194
0
            Err(_) => panic!("p={:?} is outside range [0.0, 1.0]", p),
195
        }
196
0
    }
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
0
    fn random_ratio(&mut self, numerator: u32, denominator: u32) -> bool {
226
0
        match distr::Bernoulli::from_ratio(numerator, denominator) {
227
0
            Ok(d) => self.sample(d),
228
0
            Err(_) => panic!(
229
0
                "p={}/{} is outside range [0.0, 1.0]",
230
0
                numerator, denominator
231
0
            ),
232
        }
233
0
    }
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
0
    fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T {
250
0
        distr.sample(self)
251
0
    }
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
0
    fn sample_iter<T, D>(self, distr: D) -> distr::Iter<D, Self, T>
287
0
    where
288
0
        D: Distribution<T>,
289
0
        Self: Sized,
290
0
    {
291
0
        distr.sample_iter(self)
292
0
    }
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
0
    fn fill<T: Fill + ?Sized>(&mut self, dest: &mut T) {
315
0
        dest.fill(self)
316
0
    }
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
0
    fn r#gen<T>(&mut self) -> T
325
0
    where
326
0
        StandardUniform: Distribution<T>,
327
0
    {
328
0
        self.random()
329
0
    }
330
331
    /// Alias for [`Rng::random_range`].
332
    #[inline]
333
    #[deprecated(since = "0.9.0", note = "Renamed to `random_range`")]
334
0
    fn gen_range<T, R>(&mut self, range: R) -> T
335
0
    where
336
0
        T: SampleUniform,
337
0
        R: SampleRange<T>,
338
0
    {
339
0
        self.random_range(range)
340
0
    }
341
342
    /// Alias for [`Rng::random_bool`].
343
    #[inline]
344
    #[deprecated(since = "0.9.0", note = "Renamed to `random_bool`")]
345
0
    fn gen_bool(&mut self, p: f64) -> bool {
346
0
        self.random_bool(p)
347
0
    }
348
349
    /// Alias for [`Rng::random_ratio`].
350
    #[inline]
351
    #[deprecated(since = "0.9.0", note = "Renamed to `random_ratio`")]
352
0
    fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool {
353
0
        self.random_ratio(numerator, denominator)
354
0
    }
355
}
356
357
impl<R: RngCore + ?Sized> Rng for R {}
358
359
/// Types which may be filled with random data
360
///
361
/// This trait allows arrays to be efficiently filled with random data.
362
///
363
/// Implementations are expected to be portable across machines unless
364
/// clearly documented otherwise (see the
365
/// [Chapter on Portability](https://rust-random.github.io/book/portability.html)).
366
pub trait Fill {
367
    /// Fill self with random data
368
    fn fill<R: Rng + ?Sized>(&mut self, rng: &mut R);
369
}
370
371
macro_rules! impl_fill_each {
372
    () => {};
373
    ($t:ty) => {
374
        impl Fill for [$t] {
375
0
            fn fill<R: Rng + ?Sized>(&mut self, rng: &mut R) {
376
0
                for elt in self.iter_mut() {
377
0
                    *elt = rng.random();
378
0
                }
379
0
            }
Unexecuted instantiation: <[bool] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[char] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[f32] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[f64] as rand::rng::Fill>::fill::<_>
380
        }
381
    };
382
    ($t:ty, $($tt:ty,)*) => {
383
        impl_fill_each!($t);
384
        impl_fill_each!($($tt,)*);
385
    };
386
}
387
388
impl_fill_each!(bool, char, f32, f64,);
389
390
impl Fill for [u8] {
391
0
    fn fill<R: Rng + ?Sized>(&mut self, rng: &mut R) {
392
0
        rng.fill_bytes(self)
393
0
    }
394
}
395
396
/// Call target for unsafe macros
397
0
const unsafe fn __unsafe() {}
398
399
/// Implement `Fill` for given type `$t`.
400
///
401
/// # Safety
402
/// All bit patterns of `[u8; size_of::<$t>()]` must represent values of `$t`.
403
macro_rules! impl_fill {
404
    () => {};
405
    ($t:ty) => {{
406
        // Force caller to wrap with an `unsafe` block
407
        __unsafe();
408
409
        impl Fill for [$t] {
410
0
            fn fill<R: Rng + ?Sized>(&mut self, rng: &mut R) {
411
0
                if self.len() > 0 {
412
0
                    let size = mem::size_of_val(self);
413
0
                    rng.fill_bytes(
414
0
                        // SAFETY: `self` non-null and valid for reads and writes within its `size`
415
0
                        // bytes. `self` meets the alignment requirements of `&mut [u8]`.
416
0
                        // The contents of `self` are initialized. Both `[u8]` and `[$t]` are valid
417
0
                        // for all bit-patterns of their contents (note that the SAFETY requirement
418
0
                        // on callers of this macro). `self` is not borrowed.
419
0
                        unsafe {
420
0
                            slice::from_raw_parts_mut(self.as_mut_ptr()
421
0
                                as *mut u8,
422
0
                                size
423
0
                            )
424
0
                        }
425
0
                    );
426
0
                    for x in self {
427
0
                        *x = x.to_le();
428
0
                    }
429
0
                }
430
0
            }
Unexecuted instantiation: <[u16] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[u32] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[u64] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[u128] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[i8] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[i16] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[i32] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[i64] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[i128] as rand::rng::Fill>::fill::<_>
431
        }
432
433
        impl Fill for [Wrapping<$t>] {
434
0
            fn fill<R: Rng + ?Sized>(&mut self, rng: &mut R) {
435
0
                if self.len() > 0 {
436
0
                    let size = self.len() * mem::size_of::<$t>();
437
0
                    rng.fill_bytes(
438
0
                        // SAFETY: `self` non-null and valid for reads and writes within its `size`
439
0
                        // bytes. `self` meets the alignment requirements of `&mut [u8]`.
440
0
                        // The contents of `self` are initialized. Both `[u8]` and `[$t]` are valid
441
0
                        // for all bit-patterns of their contents (note that the SAFETY requirement
442
0
                        // on callers of this macro). `self` is not borrowed.
443
0
                        unsafe {
444
0
                            slice::from_raw_parts_mut(self.as_mut_ptr()
445
0
                                as *mut u8,
446
0
                                size
447
0
                            )
448
0
                        }
449
0
                    );
450
0
                    for x in self {
451
0
                        *x = Wrapping(x.0.to_le());
452
0
                    }
453
0
                }
454
0
            }
Unexecuted instantiation: <[core::num::wrapping::Wrapping<u16>] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[core::num::wrapping::Wrapping<u32>] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[core::num::wrapping::Wrapping<u64>] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[core::num::wrapping::Wrapping<u128>] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[core::num::wrapping::Wrapping<i8>] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[core::num::wrapping::Wrapping<i16>] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[core::num::wrapping::Wrapping<i32>] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[core::num::wrapping::Wrapping<i64>] as rand::rng::Fill>::fill::<_>
Unexecuted instantiation: <[core::num::wrapping::Wrapping<i128>] as rand::rng::Fill>::fill::<_>
455
        }}
456
    };
457
    ($t:ty, $($tt:ty,)*) => {{
458
        impl_fill!($t);
459
        // TODO: this could replace above impl once Rust #32463 is fixed
460
        // impl_fill!(Wrapping<$t>);
461
        impl_fill!($($tt,)*);
462
    }}
463
}
464
465
// SAFETY: All bit patterns of `[u8; size_of::<$t>()]` represent values of `u*`.
466
const _: () = unsafe { impl_fill!(u16, u32, u64, u128,) };
467
// SAFETY: All bit patterns of `[u8; size_of::<$t>()]` represent values of `i*`.
468
const _: () = unsafe { impl_fill!(i8, i16, i32, i64, i128,) };
469
470
impl<T, const N: usize> Fill for [T; N]
471
where
472
    [T]: Fill,
473
{
474
0
    fn fill<R: Rng + ?Sized>(&mut self, rng: &mut R) {
475
0
        <[T] as Fill>::fill(self, rng)
476
0
    }
477
}
478
479
#[cfg(test)]
480
mod test {
481
    use super::*;
482
    use crate::rngs::mock::StepRng;
483
    use crate::test::rng;
484
    #[cfg(feature = "alloc")]
485
    use alloc::boxed::Box;
486
487
    #[test]
488
    fn test_fill_bytes_default() {
489
        let mut r = StepRng::new(0x11_22_33_44_55_66_77_88, 0);
490
491
        // check every remainder mod 8, both in small and big vectors.
492
        let lengths = [0, 1, 2, 3, 4, 5, 6, 7, 80, 81, 82, 83, 84, 85, 86, 87];
493
        for &n in lengths.iter() {
494
            let mut buffer = [0u8; 87];
495
            let v = &mut buffer[0..n];
496
            r.fill_bytes(v);
497
498
            // use this to get nicer error messages.
499
            for (i, &byte) in v.iter().enumerate() {
500
                if byte == 0 {
501
                    panic!("byte {} of {} is zero", i, n)
502
                }
503
            }
504
        }
505
    }
506
507
    #[test]
508
    fn test_fill() {
509
        let x = 9041086907909331047; // a random u64
510
        let mut rng = StepRng::new(x, 0);
511
512
        // Convert to byte sequence and back to u64; byte-swap twice if BE.
513
        let mut array = [0u64; 2];
514
        rng.fill(&mut array[..]);
515
        assert_eq!(array, [x, x]);
516
        assert_eq!(rng.next_u64(), x);
517
518
        // Convert to bytes then u32 in LE order
519
        let mut array = [0u32; 2];
520
        rng.fill(&mut array[..]);
521
        assert_eq!(array, [x as u32, (x >> 32) as u32]);
522
        assert_eq!(rng.next_u32(), x as u32);
523
524
        // Check equivalence using wrapped arrays
525
        let mut warray = [Wrapping(0u32); 2];
526
        rng.fill(&mut warray[..]);
527
        assert_eq!(array[0], warray[0].0);
528
        assert_eq!(array[1], warray[1].0);
529
530
        // Check equivalence for generated floats
531
        let mut array = [0f32; 2];
532
        rng.fill(&mut array);
533
        let arr2: [f32; 2] = rng.random();
534
        assert_eq!(array, arr2);
535
    }
536
537
    #[test]
538
    fn test_fill_empty() {
539
        let mut array = [0u32; 0];
540
        let mut rng = StepRng::new(0, 1);
541
        rng.fill(&mut array);
542
        rng.fill(&mut array[..]);
543
    }
544
545
    #[test]
546
    fn test_random_range_int() {
547
        let mut r = rng(101);
548
        for _ in 0..1000 {
549
            let a = r.random_range(-4711..17);
550
            assert!((-4711..17).contains(&a));
551
            let a: i8 = r.random_range(-3..42);
552
            assert!((-3..42).contains(&a));
553
            let a: u16 = r.random_range(10..99);
554
            assert!((10..99).contains(&a));
555
            let a: i32 = r.random_range(-100..2000);
556
            assert!((-100..2000).contains(&a));
557
            let a: u32 = r.random_range(12..=24);
558
            assert!((12..=24).contains(&a));
559
560
            assert_eq!(r.random_range(..1u32), 0u32);
561
            assert_eq!(r.random_range(-12i64..-11), -12i64);
562
            assert_eq!(r.random_range(3_000_000..3_000_001), 3_000_000);
563
        }
564
    }
565
566
    #[test]
567
    fn test_random_range_float() {
568
        let mut r = rng(101);
569
        for _ in 0..1000 {
570
            let a = r.random_range(-4.5..1.7);
571
            assert!((-4.5..1.7).contains(&a));
572
            let a = r.random_range(-1.1..=-0.3);
573
            assert!((-1.1..=-0.3).contains(&a));
574
575
            assert_eq!(r.random_range(0.0f32..=0.0), 0.);
576
            assert_eq!(r.random_range(-11.0..=-11.0), -11.);
577
            assert_eq!(r.random_range(3_000_000.0..=3_000_000.0), 3_000_000.);
578
        }
579
    }
580
581
    #[test]
582
    #[should_panic]
583
    #[allow(clippy::reversed_empty_ranges)]
584
    fn test_random_range_panic_int() {
585
        let mut r = rng(102);
586
        r.random_range(5..-2);
587
    }
588
589
    #[test]
590
    #[should_panic]
591
    #[allow(clippy::reversed_empty_ranges)]
592
    fn test_random_range_panic_usize() {
593
        let mut r = rng(103);
594
        r.random_range(5..2);
595
    }
596
597
    #[test]
598
    #[allow(clippy::bool_assert_comparison)]
599
    fn test_random_bool() {
600
        let mut r = rng(105);
601
        for _ in 0..5 {
602
            assert_eq!(r.random_bool(0.0), false);
603
            assert_eq!(r.random_bool(1.0), true);
604
        }
605
    }
606
607
    #[test]
608
    fn test_rng_mut_ref() {
609
        fn use_rng(mut r: impl Rng) {
610
            let _ = r.next_u32();
611
        }
612
613
        let mut rng = rng(109);
614
        use_rng(&mut rng);
615
    }
616
617
    #[test]
618
    fn test_rng_trait_object() {
619
        use crate::distr::{Distribution, StandardUniform};
620
        let mut rng = rng(109);
621
        let mut r = &mut rng as &mut dyn RngCore;
622
        r.next_u32();
623
        r.random::<i32>();
624
        assert_eq!(r.random_range(0..1), 0);
625
        let _c: u8 = StandardUniform.sample(&mut r);
626
    }
627
628
    #[test]
629
    #[cfg(feature = "alloc")]
630
    fn test_rng_boxed_trait() {
631
        use crate::distr::{Distribution, StandardUniform};
632
        let rng = rng(110);
633
        let mut r = Box::new(rng) as Box<dyn RngCore>;
634
        r.next_u32();
635
        r.random::<i32>();
636
        assert_eq!(r.random_range(0..1), 0);
637
        let _c: u8 = StandardUniform.sample(&mut r);
638
    }
639
640
    #[test]
641
    #[cfg_attr(miri, ignore)] // Miri is too slow
642
    fn test_gen_ratio_average() {
643
        const NUM: u32 = 3;
644
        const DENOM: u32 = 10;
645
        const N: u32 = 100_000;
646
647
        let mut sum: u32 = 0;
648
        let mut rng = rng(111);
649
        for _ in 0..N {
650
            if rng.random_ratio(NUM, DENOM) {
651
                sum += 1;
652
            }
653
        }
654
        // Have Binomial(N, NUM/DENOM) distribution
655
        let expected = (NUM * N) / DENOM; // exact integer
656
        assert!(((sum - expected) as i32).abs() < 500);
657
    }
658
}