@@ -55,17 +55,20 @@ fn main () {
55
55
use mem:: size_of;
56
56
use unstable:: raw:: Slice ;
57
57
use cast;
58
+ use cmp:: Ord ;
58
59
use container:: Container ;
59
60
use iter:: { Iterator , range} ;
60
61
use local_data;
61
62
use prelude:: * ;
62
63
use str;
63
- use u64;
64
64
use vec;
65
65
66
66
pub use self :: isaac:: { IsaacRng , Isaac64Rng } ;
67
67
pub use self :: os:: OSRng ;
68
68
69
+ use self :: distributions:: { Range , IndependentSample } ;
70
+ use self :: distributions:: range:: SampleRange ;
71
+
69
72
pub mod distributions;
70
73
pub mod isaac;
71
74
pub mod os;
@@ -218,14 +221,14 @@ pub trait Rng {
218
221
vec:: from_fn ( len, |_| self . gen ( ) )
219
222
}
220
223
221
- /// Generate a random primitive integer in the range [`low`,
222
- /// `high`). Fails if ` low >= high`.
224
+ /// Generate a random value in the range [`low`, `high`). Fails if
225
+ /// `low >= high`.
223
226
///
224
- /// This gives a uniform distribution (assuming this RNG is itself
225
- /// uniform), even for edge cases like `gen_integer_range(0u8,
226
- /// 170)`, which a naive modulo operation would return numbers
227
- /// less than 85 with double the probability to those greater than
228
- /// 85 .
227
+ /// This is a convenience wrapper around
228
+ /// `distributions::Range`. If this function will be called
229
+ /// repeatedly with the same arguments, one should use `Range`, as
230
+ /// that will amortize the computations that allow for perfect
231
+ /// uniformity, as they only happen on initialization .
229
232
///
230
233
/// # Example
231
234
///
@@ -235,22 +238,15 @@ pub trait Rng {
235
238
///
236
239
/// fn main() {
237
240
/// let mut rng = rand::task_rng();
238
- /// let n: uint = rng.gen_integer_range (0u, 10);
241
+ /// let n: uint = rng.gen_range (0u, 10);
239
242
/// println!("{}", n);
240
- /// let m: int = rng.gen_integer_range (-40, 400 );
243
+ /// let m: float = rng.gen_range (-40.0, 1.3e5 );
241
244
/// println!("{}", m);
242
245
/// }
243
246
/// ```
244
- fn gen_integer_range < T : Rand + Int > ( & mut self , low : T , high : T ) -> T {
245
- assert ! ( low < high, "RNG.gen_integer_range called with low >= high" ) ;
246
- let range = ( high - low) . to_u64 ( ) . unwrap ( ) ;
247
- let accept_zone = u64:: max_value - u64:: max_value % range;
248
- loop {
249
- let rand = self . gen :: < u64 > ( ) ;
250
- if rand < accept_zone {
251
- return low + NumCast :: from ( rand % range) . unwrap ( ) ;
252
- }
253
- }
247
+ fn gen_range < T : Ord + SampleRange > ( & mut self , low : T , high : T ) -> T {
248
+ assert ! ( low < high, "Rng.gen_range called with low >= high" ) ;
249
+ Range :: new ( low, high) . ind_sample ( self )
254
250
}
255
251
256
252
/// Return a bool with a 1 in n chance of true
@@ -267,7 +263,7 @@ pub trait Rng {
267
263
/// }
268
264
/// ```
269
265
fn gen_weighted_bool ( & mut self , n : uint ) -> bool {
270
- n == 0 || self . gen_integer_range ( 0 , n) == 0
266
+ n == 0 || self . gen_range ( 0 , n) == 0
271
267
}
272
268
273
269
/// Return a random string of the specified length composed of
@@ -317,7 +313,7 @@ pub trait Rng {
317
313
if values. is_empty ( ) {
318
314
None
319
315
} else {
320
- Some ( & values[ self . gen_integer_range ( 0 u, values. len ( ) ) ] )
316
+ Some ( & values[ self . gen_range ( 0 u, values. len ( ) ) ] )
321
317
}
322
318
}
323
319
@@ -368,7 +364,7 @@ pub trait Rng {
368
364
if total == 0 u {
369
365
return None ;
370
366
}
371
- let chosen = self . gen_integer_range ( 0 u, total) ;
367
+ let chosen = self . gen_range ( 0 u, total) ;
372
368
let mut so_far = 0 u;
373
369
for item in v. iter ( ) {
374
370
so_far += item. weight ;
@@ -447,7 +443,7 @@ pub trait Rng {
447
443
// invariant: elements with index >= i have been locked in place.
448
444
i -= 1 u;
449
445
// lock element i in place.
450
- values. swap ( i, self . gen_integer_range ( 0 u, i + 1 u) ) ;
446
+ values. swap ( i, self . gen_range ( 0 u, i + 1 u) ) ;
451
447
}
452
448
}
453
449
@@ -473,7 +469,7 @@ pub trait Rng {
473
469
continue
474
470
}
475
471
476
- let k = self . gen_integer_range ( 0 , i + 1 ) ;
472
+ let k = self . gen_range ( 0 , i + 1 ) ;
477
473
if k < reservoir. len ( ) {
478
474
reservoir[ k] = elem
479
475
}
@@ -760,36 +756,36 @@ mod test {
760
756
}
761
757
762
758
#[ test]
763
- fn test_gen_integer_range ( ) {
759
+ fn test_gen_range ( ) {
764
760
let mut r = rng( ) ;
765
761
for _ in range( 0 , 1000 ) {
766
- let a = r. gen_integer_range ( -3 i, 42 ) ;
762
+ let a = r. gen_range ( -3 i, 42 ) ;
767
763
assert!( a >= -3 && a < 42 ) ;
768
- assert_eq!( r. gen_integer_range ( 0 , 1 ) , 0 ) ;
769
- assert_eq!( r. gen_integer_range ( -12 , -11 ) , -12 ) ;
764
+ assert_eq!( r. gen_range ( 0 , 1 ) , 0 ) ;
765
+ assert_eq!( r. gen_range ( -12 , -11 ) , -12 ) ;
770
766
}
771
767
772
768
for _ in range( 0 , 1000 ) {
773
- let a = r. gen_integer_range ( 10 , 42 ) ;
769
+ let a = r. gen_range ( 10 , 42 ) ;
774
770
assert!( a >= 10 && a < 42 ) ;
775
- assert_eq!( r. gen_integer_range ( 0 , 1 ) , 0 ) ;
776
- assert_eq!( r. gen_integer_range ( 3_000_000 u, 3_000_001 ) , 3_000_000 ) ;
771
+ assert_eq!( r. gen_range ( 0 , 1 ) , 0 ) ;
772
+ assert_eq!( r. gen_range ( 3_000_000 u, 3_000_001 ) , 3_000_000 ) ;
777
773
}
778
774
779
775
}
780
776
781
777
#[ test]
782
778
#[ should_fail]
783
- fn test_gen_integer_range_fail_int ( ) {
779
+ fn test_gen_range_fail_int ( ) {
784
780
let mut r = rng( ) ;
785
- r. gen_integer_range ( 5 i, -2 ) ;
781
+ r. gen_range ( 5 i, -2 ) ;
786
782
}
787
783
788
784
#[ test]
789
785
#[ should_fail]
790
- fn test_gen_integer_range_fail_uint ( ) {
786
+ fn test_gen_range_fail_uint ( ) {
791
787
let mut r = rng( ) ;
792
- r. gen_integer_range ( 5 u, 2 u) ;
788
+ r. gen_range ( 5 u, 2 u) ;
793
789
}
794
790
795
791
#[ test]
@@ -894,7 +890,7 @@ mod test {
894
890
let mut r = task_rng( ) ;
895
891
r. gen :: <int>( ) ;
896
892
assert_eq!( r. shuffle( ~[ 1 , 1 , 1 ] ) , ~[ 1 , 1 , 1 ] ) ;
897
- assert_eq!( r. gen_integer_range ( 0 u, 1 u) , 0 u) ;
893
+ assert_eq!( r. gen_range ( 0 u, 1 u) , 0 u) ;
898
894
}
899
895
900
896
#[ test]
0 commit comments