fn mul128_u64(lowbits: u128, d: u64) -> u64 {
let bot_half = ((lowbits & u64::MAX as u128) * d as u128) >> 64; let top_half = (lowbits >> 64) * d as u128;
let both_halves = bot_half + top_half; (both_halves >> 64) as u64
}
#[derive(Copy, Clone, Debug)]
pub struct FM64 {
d: u64,
m: u128,
}
impl Reduce for FM64 {
fn new(d: usize) -> Self {
Self {
d: d as u64,
m: u128::MAX / d as u128 + 1,
}
}
fn reduce(self, h: u64) -> usize {
let lowbits = self.m.wrapping_mul(h as u128);
mul128_u64(lowbits, self.d) as usize
}
}
#[derive(Copy, Clone, Debug)]
pub struct FM32 {
d: u64,
m: u64,
}
impl Reduce for FM32 {
fn new(d: usize) -> Self {
assert!(d <= u32::MAX as usize);
Self {
d: d as u64,
m: u64::MAX / d as u64 + 1,
}
}
fn reduce(self, h: u64) -> usize {
let lowbits = self.m * (h as u64);
((lowbits as u128 * self.d as u128) >> 64) as usize
}
}