use crate::constants::BITS_U64;
pub const EXP_MASK: u16 = 0x001F;
pub const FAC_SHIFT: u16 = 5;
pub const FAC_MASK: u16 = 0x000F;
pub const BIT_WIDTH_SHIFT: u16 = 9;
pub const BIT_WIDTH_MASK: u16 = 0x007F;
#[inline(always)]
pub const fn pack_params(exp: u8, fac: u8, bit_width: u8) -> u16 {
((exp as u16) & EXP_MASK)
| (((fac as u16) & FAC_MASK) << FAC_SHIFT)
| (((bit_width as u16) & BIT_WIDTH_MASK) << BIT_WIDTH_SHIFT)
}
#[inline(always)]
pub const fn unpack_params(params: u16) -> (u8, u8, u8) {
let exp = (params & EXP_MASK) as u8;
let fac = ((params >> FAC_SHIFT) & FAC_MASK) as u8;
let bit_width = ((params >> BIT_WIDTH_SHIFT) & BIT_WIDTH_MASK) as u8;
(exp, fac, bit_width)
}
#[inline(always)]
pub const fn bits_needed(max_val: u64) -> u8 {
(u64::BITS - max_val.leading_zeros()) as u8
}
#[inline(always)]
pub const fn bit_mask(bit_width: u8) -> u64 {
if bit_width >= BITS_U64 as u8 {
u64::MAX
} else {
(1u64 << bit_width).wrapping_sub(1)
}
}