1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 Utilities for random number generation
14 The key functions are `random()` and `Rng::gen()`. These are polymorphic
15 and so can be used to generate any type that implements `Rand`. Type inference
16 means that often a simple call to `rand::random()` or `rng.gen()` will
17 suffice, but sometimes an annotation is required, e.g. `rand::random::<f64>()`.
19 See the `distributions` submodule for sampling random numbers from
20 distributions like normal and exponential.
24 There is built-in support for a RNG associated with each task stored
25 in task-local storage. This RNG can be accessed via `task_rng`, or
26 used implicitly via `random`. This RNG is normally randomly seeded
27 from an operating-system source of randomness, e.g. `/dev/urandom` on
28 Unix systems, and will automatically reseed itself from this source
29 after generating 32 KiB of random data.
31 # Cryptographic security
33 An application that requires an entropy source for cryptographic purposes
34 must use `OSRng`, which reads randomness from the source that the operating
35 system provides (e.g. `/dev/urandom` on Unixes or `CryptGenRandom()` on Windows).
36 The other random number generators provided by this module are not suitable
39 *Note*: many Unix systems provide `/dev/random` as well as `/dev/urandom`.
40 This module uses `/dev/urandom` for the following reasons:
42 - On Linux, `/dev/random` may block if entropy pool is empty; `/dev/urandom` will not block.
43 This does not mean that `/dev/random` provides better output than
44 `/dev/urandom`; the kernel internally runs a cryptographically secure pseudorandom
45 number generator (CSPRNG) based on entropy pool for random number generation,
46 so the "quality" of `/dev/random` is not better than `/dev/urandom` in most cases.
47 However, this means that `/dev/urandom` can yield somewhat predictable randomness
48 if the entropy pool is very small, such as immediately after first booting.
49 If an application likely to be run soon after first booting, or on a system with very
50 few entropy sources, one should consider using `/dev/random` via `ReaderRng`.
51 - On some systems (e.g. FreeBSD, OpenBSD and Mac OS X) there is no difference
52 between the two sources. (Also note that, on some systems e.g. FreeBSD, both `/dev/random`
53 and `/dev/urandom` may block once if the CSPRNG has not seeded yet.)
60 let mut rng = rand::task_rng();
61 if rng.gen() { // bool
62 println!("int: {}, uint: {}", rng.gen::<int>(), rng.gen::<uint>())
67 let tuple_ptr = rand::random::<Box<(f64, char)>>();
68 println!("{:?}", tuple_ptr)
72 #![crate_id = "rand#0.11.0-pre"]
73 #![license = "MIT/ASL2"]
74 #![crate_type = "dylib"]
75 #![crate_type = "rlib"]
76 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
77 html_favicon_url = "http://www.rust-lang.org/favicon.ico",
78 html_root_url = "http://static.rust-lang.org/doc/master")]
80 #![feature(macro_rules, managed_boxes, phase)]
81 #![deny(deprecated_owned_vector)]
84 #[phase(syntax, link)] extern crate log;
86 use std::io::IoResult;
87 use std::kinds::marker;
89 use std::strbuf::StrBuf;
91 pub use isaac::{IsaacRng, Isaac64Rng};
94 use distributions::{Range, IndependentSample};
95 use distributions::range::SampleRange;
97 pub mod distributions;
104 /// A type that can be randomly generated using an `Rng`.
106 /// Generates a random instance of this type using the specified source of
108 fn rand<R: Rng>(rng: &mut R) -> Self;
111 /// A random number generator.
113 /// Return the next random u32.
115 /// This rarely needs to be called directly, prefer `r.gen()` to
117 // FIXME #7771: Should be implemented in terms of next_u64
118 fn next_u32(&mut self) -> u32;
120 /// Return the next random u64.
122 /// By default this is implemented in terms of `next_u32`. An
123 /// implementation of this trait must provide at least one of
124 /// these two methods. Similarly to `next_u32`, this rarely needs
125 /// to be called directly, prefer `r.gen()` to `r.next_u64()`.
126 fn next_u64(&mut self) -> u64 {
127 (self.next_u32() as u64 << 32) | (self.next_u32() as u64)
130 /// Fill `dest` with random data.
132 /// This has a default implementation in terms of `next_u64` and
133 /// `next_u32`, but should be overridden by implementations that
134 /// offer a more efficient solution than just calling those
135 /// methods repeatedly.
137 /// This method does *not* have a requirement to bear any fixed
138 /// relationship to the other methods, for example, it does *not*
139 /// have to result in the same output as progressively filling
140 /// `dest` with `self.gen::<u8>()`, and any such behaviour should
141 /// not be relied upon.
143 /// This method should guarantee that `dest` is entirely filled
144 /// with new data, and may fail if this is impossible
145 /// (e.g. reading past the end of a file that is being used as the
146 /// source of randomness).
151 /// use rand::{task_rng, Rng};
153 /// let mut v = [0u8, .. 13579];
154 /// task_rng().fill_bytes(v);
155 /// println!("{:?}", v);
157 fn fill_bytes(&mut self, dest: &mut [u8]) {
158 // this could, in theory, be done by transmuting dest to a
159 // [u64], but this is (1) likely to be undefined behaviour for
160 // LLVM, (2) has to be very careful about alignment concerns,
161 // (3) adds more `unsafe` that needs to be checked, (4)
162 // probably doesn't give much performance gain if
163 // optimisations are on.
166 for byte in dest.mut_iter() {
168 // we could micro-optimise here by generating a u32 if
169 // we only need a few more bytes to fill the vector
171 num = self.next_u64();
175 *byte = (num & 0xff) as u8;
181 /// Return a random value of a `Rand` type.
186 /// use rand::{task_rng, Rng};
188 /// let mut rng = task_rng();
189 /// let x: uint = rng.gen();
190 /// println!("{}", x);
191 /// println!("{:?}", rng.gen::<(f64, bool)>());
194 fn gen<T: Rand>(&mut self) -> T {
198 /// Return a random vector of the specified length.
203 /// use rand::{task_rng, Rng};
205 /// let mut rng = task_rng();
206 /// let x: Vec<uint> = rng.gen_vec(10);
207 /// println!("{}", x);
208 /// println!("{}", rng.gen_vec::<(f64, bool)>(5));
210 fn gen_vec<T: Rand>(&mut self, len: uint) -> Vec<T> {
211 Vec::from_fn(len, |_| self.gen())
214 /// Generate a random value in the range [`low`, `high`). Fails if
217 /// This is a convenience wrapper around
218 /// `distributions::Range`. If this function will be called
219 /// repeatedly with the same arguments, one should use `Range`, as
220 /// that will amortize the computations that allow for perfect
221 /// uniformity, as they only happen on initialization.
226 /// use rand::{task_rng, Rng};
228 /// let mut rng = task_rng();
229 /// let n: uint = rng.gen_range(0u, 10);
230 /// println!("{}", n);
231 /// let m: f64 = rng.gen_range(-40.0, 1.3e5);
232 /// println!("{}", m);
234 fn gen_range<T: Ord + SampleRange>(&mut self, low: T, high: T) -> T {
235 assert!(low < high, "Rng.gen_range called with low >= high");
236 Range::new(low, high).ind_sample(self)
239 /// Return a bool with a 1 in n chance of true
244 /// use rand::{task_rng, Rng};
246 /// let mut rng = task_rng();
247 /// println!("{:b}", rng.gen_weighted_bool(3));
249 fn gen_weighted_bool(&mut self, n: uint) -> bool {
250 n == 0 || self.gen_range(0, n) == 0
253 /// Return a random string of the specified length composed of
259 /// use rand::{task_rng, Rng};
261 /// println!("{}", task_rng().gen_ascii_str(10));
263 fn gen_ascii_str(&mut self, len: uint) -> StrBuf {
264 static GEN_ASCII_STR_CHARSET: &'static [u8] = bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ\
265 abcdefghijklmnopqrstuvwxyz\
267 let mut s = StrBuf::with_capacity(len);
268 for _ in range(0, len) {
269 s.push_char(*self.choose(GEN_ASCII_STR_CHARSET).unwrap() as char)
274 /// Return a random element from `values`.
276 /// Return `None` if `values` is empty.
281 /// use rand::{task_rng, Rng};
283 /// let choices = [1, 2, 4, 8, 16, 32];
284 /// let mut rng = task_rng();
285 /// println!("{}", rng.choose(choices));
286 /// assert_eq!(rng.choose(choices.slice_to(0)), None);
288 fn choose<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> {
289 if values.is_empty() {
292 Some(&values[self.gen_range(0u, values.len())])
296 /// Deprecated name for `choose()`.
297 #[deprecated = "replaced by .choose()"]
298 fn choose_option<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> {
302 /// Shuffle a mutable slice in place.
307 /// use rand::{task_rng, Rng};
309 /// let mut rng = task_rng();
310 /// let mut y = [1,2,3];
312 /// println!("{}", y.as_slice());
314 /// println!("{}", y.as_slice());
316 fn shuffle<T>(&mut self, values: &mut [T]) {
317 let mut i = values.len();
319 // invariant: elements with index >= i have been locked in place.
321 // lock element i in place.
322 values.swap(i, self.gen_range(0u, i + 1u));
326 /// Randomly sample up to `n` elements from an iterator.
331 /// use rand::{task_rng, Rng};
333 /// let mut rng = task_rng();
334 /// let sample = rng.sample(range(1, 100), 5);
335 /// println!("{}", sample);
337 fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> Vec<A> {
338 let mut reservoir = Vec::with_capacity(n);
339 for (i, elem) in iter.enumerate() {
341 reservoir.push(elem);
345 let k = self.gen_range(0, i + 1);
346 if k < reservoir.len() {
347 *reservoir.get_mut(k) = elem
354 /// A random number generator that can be explicitly seeded to produce
355 /// the same stream of randomness multiple times.
356 pub trait SeedableRng<Seed>: Rng {
357 /// Reseed an RNG with the given seed.
362 /// use rand::{Rng, SeedableRng, StdRng};
364 /// let mut rng: StdRng = SeedableRng::from_seed(&[1, 2, 3, 4]);
365 /// println!("{}", rng.gen::<f64>());
366 /// rng.reseed([5, 6, 7, 8]);
367 /// println!("{}", rng.gen::<f64>());
369 fn reseed(&mut self, Seed);
371 /// Create a new RNG with the given seed.
376 /// use rand::{Rng, SeedableRng, StdRng};
378 /// let mut rng: StdRng = SeedableRng::from_seed(&[1, 2, 3, 4]);
379 /// println!("{}", rng.gen::<f64>());
381 fn from_seed(seed: Seed) -> Self;
384 /// The standard RNG. This is designed to be efficient on the current
386 #[cfg(not(target_word_size="64"))]
387 pub struct StdRng { rng: IsaacRng }
389 /// The standard RNG. This is designed to be efficient on the current
391 #[cfg(target_word_size="64")]
392 pub struct StdRng { rng: Isaac64Rng }
395 /// Create a randomly seeded instance of `StdRng`.
397 /// This is a very expensive operation as it has to read
398 /// randomness from the operating system and use this in an
399 /// expensive seeding operation. If one is only generating a small
400 /// number of random numbers, or doesn't need the utmost speed for
401 /// generating each number, `task_rng` and/or `random` may be more
404 /// Reading the randomness from the OS may fail, and any error is
405 /// propagated via the `IoResult` return value.
406 #[cfg(not(target_word_size="64"))]
407 pub fn new() -> IoResult<StdRng> {
408 IsaacRng::new().map(|r| StdRng { rng: r })
410 /// Create a randomly seeded instance of `StdRng`.
412 /// This is a very expensive operation as it has to read
413 /// randomness from the operating system and use this in an
414 /// expensive seeding operation. If one is only generating a small
415 /// number of random numbers, or doesn't need the utmost speed for
416 /// generating each number, `task_rng` and/or `random` may be more
419 /// Reading the randomness from the OS may fail, and any error is
420 /// propagated via the `IoResult` return value.
421 #[cfg(target_word_size="64")]
422 pub fn new() -> IoResult<StdRng> {
423 Isaac64Rng::new().map(|r| StdRng { rng: r })
427 impl Rng for StdRng {
429 fn next_u32(&mut self) -> u32 {
434 fn next_u64(&mut self) -> u64 {
439 impl<'a> SeedableRng<&'a [uint]> for StdRng {
440 fn reseed(&mut self, seed: &'a [uint]) {
441 // the internal RNG can just be seeded from the above
443 self.rng.reseed(unsafe {mem::transmute(seed)})
446 fn from_seed(seed: &'a [uint]) -> StdRng {
447 StdRng { rng: SeedableRng::from_seed(unsafe {mem::transmute(seed)}) }
451 /// Create a weak random number generator with a default algorithm and seed.
453 /// It returns the fastest `Rng` algorithm currently available in Rust without
454 /// consideration for cryptography or security. If you require a specifically
455 /// seeded `Rng` for consistency over time you should pick one algorithm and
456 /// create the `Rng` yourself.
458 /// This will read randomness from the operating system to seed the
460 pub fn weak_rng() -> XorShiftRng {
461 match XorShiftRng::new() {
463 Err(e) => fail!("weak_rng: failed to create seeded RNG: {}", e)
467 /// An Xorshift[1] random number
470 /// The Xorshift algorithm is not suitable for cryptographic purposes
471 /// but is very fast. If you do not know for sure that it fits your
472 /// requirements, use a more secure one such as `IsaacRng` or `OSRng`.
474 /// [1]: Marsaglia, George (July 2003). ["Xorshift
475 /// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
476 /// Statistical Software*. Vol. 8 (Issue 14).
477 pub struct XorShiftRng {
484 impl Rng for XorShiftRng {
486 fn next_u32(&mut self) -> u32 {
488 let t = x ^ (x << 11);
493 self.w = w ^ (w >> 19) ^ (t ^ (t >> 8));
498 impl SeedableRng<[u32, .. 4]> for XorShiftRng {
499 /// Reseed an XorShiftRng. This will fail if `seed` is entirely 0.
500 fn reseed(&mut self, seed: [u32, .. 4]) {
501 assert!(!seed.iter().all(|&x| x == 0),
502 "XorShiftRng.reseed called with an all zero seed.");
510 /// Create a new XorShiftRng. This will fail if `seed` is entirely 0.
511 fn from_seed(seed: [u32, .. 4]) -> XorShiftRng {
512 assert!(!seed.iter().all(|&x| x == 0),
513 "XorShiftRng::from_seed called with an all zero seed.");
525 /// Create an xor shift random number generator with a random seed.
526 pub fn new() -> IoResult<XorShiftRng> {
527 let mut s = [0u8, ..16];
528 let mut r = try!(OSRng::new());
532 if !s.iter().all(|x| *x == 0) {
536 let s: [u32, ..4] = unsafe { mem::transmute(s) };
537 Ok(SeedableRng::from_seed(s))
541 /// Controls how the task-local RNG is reseeded.
542 struct TaskRngReseeder;
544 impl reseeding::Reseeder<StdRng> for TaskRngReseeder {
545 fn reseed(&mut self, rng: &mut StdRng) {
546 *rng = match StdRng::new() {
548 Err(e) => fail!("could not reseed task_rng: {}", e)
552 static TASK_RNG_RESEED_THRESHOLD: uint = 32_768;
553 type TaskRngInner = reseeding::ReseedingRng<StdRng, TaskRngReseeder>;
554 /// The task-local RNG.
556 // This points into TLS (specifically, it points to the endpoint
557 // of a Box stored in TLS, to make it robust against TLS moving
558 // things internally) and so this struct cannot be legally
559 // transferred between tasks *and* it's unsafe to deallocate the
560 // RNG other than when a task is finished.
562 // The use of unsafe code here is OK if the invariants above are
563 // satisfied; and it allows us to avoid (unnecessarily) using a
564 // GC'd or RC'd pointer.
565 rng: *mut TaskRngInner,
566 marker: marker::NoSend,
569 /// Retrieve the lazily-initialized task-local random number
570 /// generator, seeded by the system. Intended to be used in method
571 /// chaining style, e.g. `task_rng().gen::<int>()`.
573 /// The RNG provided will reseed itself from the operating system
574 /// after generating a certain amount of randomness.
576 /// The internal RNG used is platform and architecture dependent, even
577 /// if the operating system random number generator is rigged to give
578 /// the same sequence always. If absolute consistency is required,
579 /// explicitly select an RNG, e.g. `IsaacRng` or `Isaac64Rng`.
580 pub fn task_rng() -> TaskRng {
581 // used to make space in TLS for a random number generator
582 local_data_key!(TASK_RNG_KEY: Box<TaskRngInner>)
584 match TASK_RNG_KEY.get() {
586 let r = match StdRng::new() {
588 Err(e) => fail!("could not initialize task_rng: {}", e)
590 let mut rng = box reseeding::ReseedingRng::new(r,
591 TASK_RNG_RESEED_THRESHOLD,
593 let ptr = &mut *rng as *mut TaskRngInner;
595 TASK_RNG_KEY.replace(Some(rng));
597 TaskRng { rng: ptr, marker: marker::NoSend }
599 Some(rng) => TaskRng {
600 rng: &**rng as *_ as *mut TaskRngInner,
601 marker: marker::NoSend
606 impl Rng for TaskRng {
607 fn next_u32(&mut self) -> u32 {
608 unsafe { (*self.rng).next_u32() }
611 fn next_u64(&mut self) -> u64 {
612 unsafe { (*self.rng).next_u64() }
616 fn fill_bytes(&mut self, bytes: &mut [u8]) {
617 unsafe { (*self.rng).fill_bytes(bytes) }
621 /// Generate a random value using the task-local random number
627 /// use rand::random;
630 /// let x = random();
631 /// println!("{}", 2u * x);
633 /// println!("{}", random::<f64>());
637 pub fn random<T: Rand>() -> T {
641 /// A wrapper for generating floating point numbers uniformly in the
642 /// open interval `(0,1)` (not including either endpoint).
644 /// Use `Closed01` for the closed interval `[0,1]`, and the default
645 /// `Rand` implementation for `f32` and `f64` for the half-open
650 /// use rand::{random, Open01};
652 /// let Open01(val) = random::<Open01<f32>>();
653 /// println!("f32 from (0,1): {}", val);
655 pub struct Open01<F>(pub F);
657 /// A wrapper for generating floating point numbers uniformly in the
658 /// closed interval `[0,1]` (including both endpoints).
660 /// Use `Open01` for the closed interval `(0,1)`, and the default
661 /// `Rand` implementation of `f32` and `f64` for the half-open
666 /// use rand::{random, Closed01};
668 /// let Closed01(val) = random::<Closed01<f32>>();
669 /// println!("f32 from [0,1]: {}", val);
671 pub struct Closed01<F>(pub F);
675 use super::{Rng, task_rng, random, SeedableRng, StdRng};
677 struct ConstRng { i: u64 }
678 impl Rng for ConstRng {
679 fn next_u32(&mut self) -> u32 { self.i as u32 }
680 fn next_u64(&mut self) -> u64 { self.i }
682 // no fill_bytes on purpose
686 fn test_fill_bytes_default() {
687 let mut r = ConstRng { i: 0x11_22_33_44_55_66_77_88 };
689 // check every remainder mod 8, both in small and big vectors.
690 let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
691 80, 81, 82, 83, 84, 85, 86, 87];
692 for &n in lengths.iter() {
693 let mut v = Vec::from_elem(n, 0u8);
694 r.fill_bytes(v.as_mut_slice());
696 // use this to get nicer error messages.
697 for (i, &byte) in v.iter().enumerate() {
699 fail!("byte {} of {} is zero", i, n)
706 fn test_gen_range() {
707 let mut r = task_rng();
708 for _ in range(0, 1000) {
709 let a = r.gen_range(-3i, 42);
710 assert!(a >= -3 && a < 42);
711 assert_eq!(r.gen_range(0, 1), 0);
712 assert_eq!(r.gen_range(-12, -11), -12);
715 for _ in range(0, 1000) {
716 let a = r.gen_range(10, 42);
717 assert!(a >= 10 && a < 42);
718 assert_eq!(r.gen_range(0, 1), 0);
719 assert_eq!(r.gen_range(3_000_000u, 3_000_001), 3_000_000);
726 fn test_gen_range_fail_int() {
727 let mut r = task_rng();
733 fn test_gen_range_fail_uint() {
734 let mut r = task_rng();
740 let mut r = task_rng();
741 let a = r.gen::<f64>();
742 let b = r.gen::<f64>();
743 debug!("{:?}", (a, b));
747 fn test_gen_weighted_bool() {
748 let mut r = task_rng();
749 assert_eq!(r.gen_weighted_bool(0u), true);
750 assert_eq!(r.gen_weighted_bool(1u), true);
754 fn test_gen_ascii_str() {
755 let mut r = task_rng();
756 debug!("{}", r.gen_ascii_str(10u));
757 debug!("{}", r.gen_ascii_str(10u));
758 debug!("{}", r.gen_ascii_str(10u));
759 assert_eq!(r.gen_ascii_str(0u).len(), 0u);
760 assert_eq!(r.gen_ascii_str(10u).len(), 10u);
761 assert_eq!(r.gen_ascii_str(16u).len(), 16u);
766 let mut r = task_rng();
767 assert_eq!(r.gen_vec::<u8>(0u).len(), 0u);
768 assert_eq!(r.gen_vec::<u8>(10u).len(), 10u);
769 assert_eq!(r.gen_vec::<f64>(16u).len(), 16u);
774 let mut r = task_rng();
775 assert_eq!(r.choose([1, 1, 1]).map(|&x|x), Some(1));
778 assert_eq!(r.choose(v), None);
783 let mut r = task_rng();
784 let empty: &mut [int] = &mut [];
788 assert_eq!(one.as_slice(), &[1]);
790 let mut two = [1, 2];
792 assert!(two == [1, 2] || two == [2, 1]);
794 let mut x = [1, 1, 1];
796 assert_eq!(x.as_slice(), &[1, 1, 1]);
801 let mut r = task_rng();
803 let mut v = [1, 1, 1];
805 assert_eq!(v.as_slice(), &[1, 1, 1]);
806 assert_eq!(r.gen_range(0u, 1u), 0u);
811 // not sure how to test this aside from just getting some values
812 let _n : uint = random();
813 let _f : f32 = random();
814 let _o : Option<Option<i8>> = random();
818 Box<Option<Box<(@u32, Box<(@bool,)>)>>>),
819 (u8, i8, u16, i16, u32, i32, u64, i64),
820 (f32, (f64, (f64,)))) = random();
828 let mut r = task_rng();
829 let vals = range(min_val, max_val).collect::<Vec<int>>();
830 let small_sample = r.sample(vals.iter(), 5);
831 let large_sample = r.sample(vals.iter(), vals.len() + 5);
833 assert_eq!(small_sample.len(), 5);
834 assert_eq!(large_sample.len(), vals.len());
836 assert!(small_sample.iter().all(|e| {
837 **e >= min_val && **e <= max_val
842 fn test_std_rng_seeded() {
843 let s = task_rng().gen_vec::<uint>(256);
844 let mut ra: StdRng = SeedableRng::from_seed(s.as_slice());
845 let mut rb: StdRng = SeedableRng::from_seed(s.as_slice());
846 assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
850 fn test_std_rng_reseed() {
851 let s = task_rng().gen_vec::<uint>(256);
852 let mut r: StdRng = SeedableRng::from_seed(s.as_slice());
853 let string1 = r.gen_ascii_str(100);
855 r.reseed(s.as_slice());
857 let string2 = r.gen_ascii_str(100);
858 assert_eq!(string1, string2);
863 static RAND_BENCH_N: u64 = 100;
868 use self::test::Bencher;
869 use {XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N};
870 use std::mem::size_of;
873 fn rand_xorshift(b: &mut Bencher) {
874 let mut rng = XorShiftRng::new().unwrap();
876 for _ in range(0, RAND_BENCH_N) {
880 b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
884 fn rand_isaac(b: &mut Bencher) {
885 let mut rng = IsaacRng::new().unwrap();
887 for _ in range(0, RAND_BENCH_N) {
891 b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
895 fn rand_isaac64(b: &mut Bencher) {
896 let mut rng = Isaac64Rng::new().unwrap();
898 for _ in range(0, RAND_BENCH_N) {
902 b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
906 fn rand_std(b: &mut Bencher) {
907 let mut rng = StdRng::new().unwrap();
909 for _ in range(0, RAND_BENCH_N) {
913 b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
917 fn rand_shuffle_100(b: &mut Bencher) {
918 let mut rng = XorShiftRng::new().unwrap();
919 let x : &mut[uint] = [1,..100];