@@ -401,7 +401,7 @@ pub trait Rng: RngCore {
401401 /// ```
402402 ///
403403 /// [`Uniform`]: distributions/uniform/struct.Uniform.html
404- fn gen_range < T : PartialOrd + SampleUniform > ( & mut self , low : T , high : T ) -> T {
404+ fn gen_range < T : SampleUniform > ( & mut self , low : T , high : T ) -> T {
405405 T :: Sampler :: sample_single ( low, high, self )
406406 }
407407
@@ -523,8 +523,6 @@ pub trait Rng: RngCore {
523523
524524 /// Return a bool with a probability `p` of being true.
525525 ///
526- /// This is a wrapper around [`distributions::Bernoulli`].
527- ///
528526 /// # Example
529527 ///
530528 /// ```
@@ -536,15 +534,38 @@ pub trait Rng: RngCore {
536534 ///
537535 /// # Panics
538536 ///
539- /// If `p` < 0 or `p` > 1.
540- ///
541- /// [`distributions::Bernoulli`]: distributions/bernoulli/struct.Bernoulli.html
537+ /// If `p < 0` or `p > 1`.
542538 #[ inline]
543539 fn gen_bool ( & mut self , p : f64 ) -> bool {
544540 let d = distributions:: Bernoulli :: new ( p) ;
545541 self . sample ( d)
546542 }
547543
544+ /// Return a bool with a probability of `numerator/denominator` of being
545+ /// true. I.e. `gen_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
546+ /// returning true. If `numerator == denominator`, then the returned value
547+ /// is guaranteed to be `true`. If `numerator == 0`, then the returned
548+ /// value is guaranteed to be `false`.
549+ ///
550+ /// # Panics
551+ ///
552+ /// If `denominator == 0` or `numerator > denominator`.
553+ ///
554+ /// # Example
555+ ///
556+ /// ```
557+ /// use rand::{thread_rng, Rng};
558+ ///
559+ /// let mut rng = thread_rng();
560+ /// println!("{}", rng.gen_ratio(2, 3));
561+ /// ```
562+ ///
563+ #[ inline]
564+ fn gen_ratio ( & mut self , numerator : u32 , denominator : u32 ) -> bool {
565+ let d = distributions:: Bernoulli :: from_ratio ( numerator, denominator) ;
566+ self . sample ( d)
567+ }
568+
548569 /// Return a random element from `values`.
549570 ///
550571 /// Return `None` if `values` is empty.
@@ -1196,4 +1217,21 @@ mod test {
11961217 ( u8 , i8 , u16 , i16 , u32 , i32 , u64 , i64 ) ,
11971218 ( f32 , ( f64 , ( f64 , ) ) ) ) = random ( ) ;
11981219 }
1220+
1221+ #[ test]
1222+ fn test_gen_ratio_average ( ) {
1223+ const NUM : u32 = 3 ;
1224+ const DENOM : u32 = 10 ;
1225+ const N : u32 = 100_000 ;
1226+
1227+ let mut sum: u32 = 0 ;
1228+ let mut rng = rng ( 111 ) ;
1229+ for _ in 0 ..N {
1230+ if rng. gen_ratio ( NUM , DENOM ) {
1231+ sum += 1 ;
1232+ }
1233+ }
1234+ let avg = ( sum as f64 ) / ( N as f64 ) ;
1235+ assert ! ( ( avg - ( NUM as f64 ) /( DENOM as f64 ) ) . abs( ) < 1e-3 ) ;
1236+ }
11991237}
0 commit comments