1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
use bitops::*; use msb::*; use lsb::*; pub trait Rounding { fn rounddown_pow2(x: Self) -> Self; fn roundup_pow2(x: Self) -> Self; } pub fn rounddown_pow2<T: Rounding>(x: T) -> T { T::rounddown_pow2(x) } pub fn roundup_pow2<T: Rounding>(x: T) -> T { T::roundup_pow2(x) } macro_rules! rounding_impl { ( $t:ty) => { impl Rounding for $t { fn rounddown_pow2(x: $t) -> $t { let msb_index = msb(x); let one: $t = 1; assert!(msb_index >= 0); one << msb_index } fn roundup_pow2(x: $t) -> $t { let mut msb_index = msb(x); let lsb_index = lsb(x); let one: $t = 1; let bitlen = bit_length::<$t>(); assert!(msb_index >= 0 && lsb_index >= 0); if msb_index != lsb_index { msb_index += 1; } assert!(msb_index < bitlen as i8); one << msb_index } } }; } rounding_impl!(u8); rounding_impl!(u16); rounding_impl!(u32); rounding_impl!(u64);