File tree Expand file tree Collapse file tree 1 file changed +34
-0
lines changed Expand file tree Collapse file tree 1 file changed +34
-0
lines changed Original file line number Diff line number Diff line change @@ -20,6 +20,40 @@ pub fn abort_on_panic<T>(f: impl FnOnce() -> T) -> T {
20
20
t
21
21
}
22
22
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
+
23
57
/// Add additional context to errors
24
58
pub ( crate ) trait Context {
25
59
fn context ( self , message : impl Fn ( ) -> String ) -> Self ;
You can’t perform that action at this time.
0 commit comments