@@ -465,6 +465,8 @@ macro_rules! uniform_int_64_impl {
465465    ( $ty: ty,  $unsigned: ident)  => { 
466466        impl  UniformInt <$ty> { 
467467            /// Sample, Canon's method variant 
468+              /// 
469+              /// Variant: potential increase to bias (uses a single `u64` sample). 
468470             #[ inline] 
469471            pub  fn  sample_canon_64<R :  Rng  + ?Sized >( & self ,  rng:  & mut  R )  -> $ty { 
470472                let  range = self . range as  $unsigned as  u64 ; 
@@ -476,6 +478,35 @@ macro_rules! uniform_int_64_impl {
476478                // bias is at most 1 in 2.pow(56) for i8, 1 in 2.pow(48) for i16 
477479                self . low. wrapping_add( result as  $ty) 
478480            } 
481+ 
482+             /// Sample single inclusive, using Canon's method variant 
483+              /// 
484+              /// Variant: potential increase to bias (uses a single `u64` sample). 
485+              #[ inline] 
486+             pub  fn  sample_single_inclusive_canon_64<R :  Rng  + ?Sized ,  B1 ,  B2 >( 
487+                 low_b:  B1 ,  high_b:  B2 ,  rng:  & mut  R , 
488+             )  -> $ty
489+             where 
490+                 B1 :  SampleBorrow <$ty> + Sized , 
491+                 B2 :  SampleBorrow <$ty> + Sized , 
492+             { 
493+                 let  low = * low_b. borrow( ) ; 
494+                 let  high = * high_b. borrow( ) ; 
495+                 assert!( 
496+                     low <= high, 
497+                     "UniformSampler::sample_single_inclusive: low > high" 
498+                 ) ; 
499+                 let  range = high. wrapping_sub( low) . wrapping_add( 1 )  as  $unsigned as  u64 ; 
500+                 if  range == 0  { 
501+                     // Range is MAX+1 (unrepresentable), so we need a special case 
502+                     return  rng. gen ( ) ; 
503+                 } 
504+ 
505+                 // generate a sample using a sensible integer type 
506+                 let  ( result,  _lo1)  = rng. gen :: <u64 >( ) . wmul( range) ; 
507+                 // bias is at most 1 in 2.pow(56) for i8, 1 in 2.pow(48) for i16 
508+                 low. wrapping_add( result as  $ty) 
509+             } 
479510        } 
480511    } 
481512} 
@@ -490,6 +521,18 @@ macro_rules! uniform_int_64void_impl {
490521            pub  fn  sample_canon_64<R :  Rng  + ?Sized >( & self ,  _rng:  & mut  R )  -> $ty { 
491522                Default :: default ( )  // not used 
492523            } 
524+ 
525+             /// Sample single inclusive, using Canon's method variant 
526+              #[ inline] 
527+             pub  fn  sample_single_inclusive_canon_64<R :  Rng  + ?Sized ,  B1 ,  B2 >( 
528+                 _low_b:  B1 ,  _high_b:  B2 ,  _rng:  & mut  R , 
529+             )  -> $ty
530+             where 
531+                 B1 :  SampleBorrow <$ty> + Sized , 
532+                 B2 :  SampleBorrow <$ty> + Sized , 
533+             { 
534+                 Default :: default ( )  // not used 
535+             } 
493536        } 
494537    } 
495538} 
@@ -519,6 +562,44 @@ impl UniformInt<i128> {
519562
520563        self . low . wrapping_add ( result as  i128 ) 
521564    } 
565+ 
566+     /// Sample single inclusive, using Canon's method variant 
567+      /// 
568+      /// Variant: potential increase to bias (uses a single `u64` sample). 
569+      #[ inline]  
570+     pub  fn  sample_single_inclusive_canon_64 < R :  Rng  + ?Sized ,  B1 ,  B2 > ( 
571+         low_b :  B1 ,  high_b :  B2 ,  rng :  & mut  R , 
572+     )  -> i128 
573+     where 
574+         B1 :  SampleBorrow < i128 >  + Sized , 
575+         B2 :  SampleBorrow < i128 >  + Sized , 
576+     { 
577+         let  low = * low_b. borrow ( ) ; 
578+         let  high = * high_b. borrow ( ) ; 
579+         assert ! ( 
580+             low <= high, 
581+             "UniformSampler::sample_single_inclusive: low > high" 
582+         ) ; 
583+         let  range = high. wrapping_sub ( low) . wrapping_add ( 1 )  as  u128 ; 
584+         if  range == 0  { 
585+             // Range is MAX+1 (unrepresentable), so we need a special case 
586+             return  rng. gen ( ) ; 
587+         } 
588+ 
589+         // generate a sample using a sensible integer type 
590+         let  ( mut  result,  lo1)  = rng. gen :: < u128 > ( ) . wmul ( range) ; 
591+ 
592+         if  lo1 > range. wrapping_neg ( )  { 
593+             // Generate more bits. Sample is multiplied by 2.pow(-192), so 
594+             // hi2 is multiplied by 2.pow(-64): 
595+             let  ( hi2,  lo2)  = ( rng. gen :: < u64 > ( )  as  u128 ) . wmul ( range) ; 
596+             debug_assert_eq ! ( hi2 >> 64 ,  0u128 ) ; 
597+             let  is_overflow = lo1. checked_add ( ( hi2 << 64 )  | ( lo2 >> 64 ) ) . is_none ( ) ; 
598+             result += is_overflow as  u128 ; 
599+         } 
600+ 
601+         low. wrapping_add ( result as  i128 ) 
602+     } 
522603} 
523604
524605#[ cfg( feature = "simd_support" ) ]  
0 commit comments