Skip to content

Commit e651769

Browse files
committed
Additional Canon64 variants
1 parent 0327e52 commit e651769

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

benches/uniform.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ macro_rules! bench_int {
6161
bench_dist_int_group!("Old", $T, sample, g, inputs);
6262
bench_dist_int_group!("Lemire", $T, sample_lemire, g, inputs);
6363
bench_dist_int_group!("Canon", $T, sample_canon, g, inputs);
64+
bench_dist_int_group!("Canon64", $T, sample_canon_64, g, inputs);
6465
bench_dist_int_group!("Canon-Lemire", $T, sample_canon_lemire, g, inputs);
6566
bench_dist_int_group!("Bitmask", $T, sample_bitmask, g, inputs);
6667
drop(g);
@@ -82,10 +83,6 @@ fn uniform_int(c: &mut Criterion) {
8283
bench_int!(c, i32, (i32::MIN, 1));
8384
bench_int!(c, i64, (i64::MIN, 1));
8485
bench_int!(c, i128, (i128::MIN, 1));
85-
86-
let inputs = &[("high_reject", (i128::MIN, 1)), ("low_reject", (-1, 2))];
87-
let mut g = c.benchmark_group(concat!("uniform_dist_int_", stringify!(i128)));
88-
bench_dist_int_group!("Canon64", i128, sample_canon_64, g, inputs);
8986
}
9087

9188
#[cfg(feature = "simd_support")]

src/distributions/uniform/uniform_int.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,11 +461,46 @@ mod isize_int_impls {
461461
uniform_int_impl! { usize, usize, usize, usize }
462462
}
463463

464+
macro_rules! uniform_int_64_impl {
465+
($ty:ty, $unsigned:ident) => {
466+
impl UniformInt<$ty> {
467+
/// Sample, Canon's method variant
468+
#[inline]
469+
pub fn sample_canon_64<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {
470+
let range = self.range as $unsigned as u64;
471+
if range == 0 {
472+
return rng.gen();
473+
}
474+
475+
let (result, _lo1) = rng.gen::<u64>().wmul(range);
476+
// bias is at most 1 in 2.pow(56) for i8, 1 in 2.pow(48) for i16
477+
self.low.wrapping_add(result as $ty)
478+
}
479+
}
480+
}
481+
}
482+
uniform_int_64_impl!(i8, u8);
483+
uniform_int_64_impl!(i16, u16);
484+
485+
macro_rules! uniform_int_64void_impl {
486+
($ty:ty) => {
487+
impl UniformInt<$ty> {
488+
/// Sample, Canon's method variant
489+
#[inline]
490+
pub fn sample_canon_64<R: Rng + ?Sized>(&self, _rng: &mut R) -> $ty {
491+
Default::default() // not used
492+
}
493+
}
494+
}
495+
}
496+
uniform_int_64void_impl!(i32);
497+
uniform_int_64void_impl!(i64);
498+
464499
impl UniformInt<i128> {
465500
/// Sample, Canon's method variant
466501
#[inline]
467502
pub fn sample_canon_64<R: Rng + ?Sized>(&self, rng: &mut R) -> i128 {
468-
let range = self.range as i128 as u128;
503+
let range = self.range as u128;
469504
if range == 0 {
470505
return rng.gen();
471506
}

0 commit comments

Comments
 (0)