1 // Copyright 2013-2014 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.
11 //! The implementations of `Rand` for the built-in types.
22 fn rand<R: Rng>(rng: &mut R) -> int {
24 rng.gen::<i32>() as int
26 rng.gen::<i64>() as int
33 fn rand<R: Rng>(rng: &mut R) -> i8 {
40 fn rand<R: Rng>(rng: &mut R) -> i16 {
47 fn rand<R: Rng>(rng: &mut R) -> i32 {
54 fn rand<R: Rng>(rng: &mut R) -> i64 {
61 fn rand<R: Rng>(rng: &mut R) -> uint {
63 rng.gen::<u32>() as uint
65 rng.gen::<u64>() as uint
72 fn rand<R: Rng>(rng: &mut R) -> u8 {
79 fn rand<R: Rng>(rng: &mut R) -> u16 {
86 fn rand<R: Rng>(rng: &mut R) -> u32 {
93 fn rand<R: Rng>(rng: &mut R) -> u64 {
98 macro_rules! float_impls {
99 ($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident, $ignored_bits:expr) => {
101 use {Rand, Rng, Open01, Closed01};
103 static SCALE: $ty = (1u64 << $mantissa_bits) as $ty;
106 /// Generate a floating point number in the half-open
107 /// interval `[0,1)`.
109 /// See `Closed01` for the closed interval `[0,1]`,
110 /// and `Open01` for the open interval `(0,1)`.
112 fn rand<R: Rng>(rng: &mut R) -> $ty {
113 // using any more than `mantissa_bits` bits will
114 // cause (e.g.) 0xffff_ffff to correspond to 1
115 // exactly, so we need to drop some (8 for f32, 11
116 // for f64) to guarantee the open end.
117 (rng.$method_name() >> $ignored_bits) as $ty / SCALE
120 impl Rand for Open01<$ty> {
122 fn rand<R: Rng>(rng: &mut R) -> Open01<$ty> {
123 // add a small amount (specifically 2 bits below
124 // the precision of f64/f32 at 1.0), so that small
125 // numbers are larger than 0, but large numbers
126 // aren't pushed to/above 1.
127 Open01(((rng.$method_name() >> $ignored_bits) as $ty + 0.25) / SCALE)
130 impl Rand for Closed01<$ty> {
132 fn rand<R: Rng>(rng: &mut R) -> Closed01<$ty> {
133 // divide by the maximum value of the numerator to
134 // get a non-zero probability of getting exactly
136 Closed01((rng.$method_name() >> $ignored_bits) as $ty / (SCALE - 1.0))
142 float_impls! { f64_rand_impls, f64, 53, next_u64, 11 }
143 float_impls! { f32_rand_impls, f32, 24, next_u32, 8 }
147 fn rand<R: Rng>(rng: &mut R) -> char {
149 static CHAR_MASK: u32 = 0x001f_ffff;
151 // Rejection sampling. About 0.2% of numbers with at most
152 // 21-bits are invalid codepoints (surrogates), so this
153 // will succeed first go almost every time.
154 match char::from_u32(rng.next_u32() & CHAR_MASK) {
164 fn rand<R: Rng>(rng: &mut R) -> bool {
165 rng.gen::<u8>() & 1 == 1
169 macro_rules! tuple_impl {
170 // use variables to indicate the arity of the tuple
171 ($($tyvar:ident),* ) => {
172 // the trailing commas are for the 1 tuple
175 > Rand for ( $( $tyvar ),* , ) {
178 fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
180 // use the $tyvar's to get the appropriate number of
181 // repeats (they're not actually needed)
194 fn rand<R: Rng>(_: &mut R) -> () { () }
199 tuple_impl!{A, B, C, D}
200 tuple_impl!{A, B, C, D, E}
201 tuple_impl!{A, B, C, D, E, F}
202 tuple_impl!{A, B, C, D, E, F, G}
203 tuple_impl!{A, B, C, D, E, F, G, H}
204 tuple_impl!{A, B, C, D, E, F, G, H, I}
205 tuple_impl!{A, B, C, D, E, F, G, H, I, J}
207 impl<T:Rand> Rand for Option<T> {
209 fn rand<R: Rng>(rng: &mut R) -> Option<T> {
221 use std::rand::{Rng, task_rng, Open01, Closed01};
223 struct ConstantRng(u64);
224 impl Rng for ConstantRng {
225 fn next_u32(&mut self) -> u32 {
226 let ConstantRng(v) = *self;
229 fn next_u64(&mut self) -> u64 {
230 let ConstantRng(v) = *self;
236 fn floating_point_edge_cases() {
237 // the test for exact equality is correct here.
238 assert!(ConstantRng(0xffff_ffff).gen::<f32>() != 1.0)
239 assert!(ConstantRng(0xffff_ffff_ffff_ffff).gen::<f64>() != 1.0)
244 // this is unlikely to catch an incorrect implementation that
245 // generates exactly 0 or 1, but it keeps it sane.
246 let mut rng = task_rng();
247 for _ in range(0, 1_000) {
248 // strict inequalities
249 let Open01(f) = rng.gen::<Open01<f64>>();
250 assert!(0.0 < f && f < 1.0);
252 let Open01(f) = rng.gen::<Open01<f32>>();
253 assert!(0.0 < f && f < 1.0);
259 let mut rng = task_rng();
260 for _ in range(0, 1_000) {
261 // strict inequalities
262 let Closed01(f) = rng.gen::<Closed01<f64>>();
263 assert!(0.0 <= f && f <= 1.0);
265 let Closed01(f) = rng.gen::<Closed01<f32>>();
266 assert!(0.0 <= f && f <= 1.0);