Skip to content

Commit 75ab721

Browse files
bring back random
1 parent e082634 commit 75ab721

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

src/utils.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,40 @@ pub fn abort_on_panic<T>(f: impl FnOnce() -> T) -> T {
2020
t
2121
}
2222

23+
/// Generates a random number in `0..n`.
24+
#[cfg(feature = "unstable")]
25+
pub fn random(n: u32) -> u32 {
26+
use std::cell::Cell;
27+
use std::num::Wrapping;
28+
29+
thread_local! {
30+
static RNG: Cell<Wrapping<u32>> = {
31+
// Take the address of a local value as seed.
32+
let mut x = 0i32;
33+
let r = &mut x;
34+
let addr = r as *mut i32 as usize;
35+
Cell::new(Wrapping(addr as u32))
36+
}
37+
}
38+
39+
RNG.with(|rng| {
40+
// This is the 32-bit variant of Xorshift.
41+
//
42+
// Source: https://en.wikipedia.org/wiki/Xorshift
43+
let mut x = rng.get();
44+
x ^= x << 13;
45+
x ^= x >> 17;
46+
x ^= x << 5;
47+
rng.set(x);
48+
49+
// This is a fast alternative to `x % n`.
50+
//
51+
// Author: Daniel Lemire
52+
// Source: https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
53+
((u64::from(x.0)).wrapping_mul(u64::from(n)) >> 32) as u32
54+
})
55+
}
56+
2357
/// Add additional context to errors
2458
pub(crate) trait Context {
2559
fn context(self, message: impl Fn() -> String) -> Self;

0 commit comments

Comments
 (0)