use crate::Integer;
use core::ops::{BitAnd, BitOr, BitXor, Shr};
pub trait Average: Integer {
fn average_ceil(&self, other: &Self) -> Self;
fn average_floor(&self, other: &Self) -> Self;
}
impl<I> Average for I
where
I: Integer + Shr<usize, Output = I>,
for<'a, 'b> &'a I:
BitAnd<&'b I, Output = I> + BitOr<&'b I, Output = I> + BitXor<&'b I, Output = I>,
{
#[inline]
fn average_floor(&self, other: &I) -> I {
(self & other) + ((self ^ other) >> 1)
}
#[inline]
fn average_ceil(&self, other: &I) -> I {
(self | other) - ((self ^ other) >> 1)
}
}
#[inline]
pub fn average_floor<T: Average>(x: T, y: T) -> T {
x.average_floor(&y)
}
#[inline]
pub fn average_ceil<T: Average>(x: T, y: T) -> T {
x.average_ceil(&y)
}