#[inline]
pub fn ilog(v: u32) -> u8 {
if v == 0 {
0
} else {
32 - v.leading_zeros() as u8
}
}
pub fn book_map_type1_quantvals(entries: u32, dimensions: u32) -> u32 {
if dimensions == 0 {
return 0;
}
let bits = ilog(entries);
let mut vals = entries >> ((bits as u32 - 1) * (dimensions - 1) / dimensions);
loop {
let mut acc: u64 = 1;
let mut acc1: u64 = 1;
for _ in 0..dimensions {
acc = acc.saturating_mul(vals as u64);
acc1 = acc1.saturating_mul((vals + 1) as u64);
}
if acc <= entries as u64 && acc1 > entries as u64 {
return vals;
}
if acc > entries as u64 {
vals -= 1;
} else {
vals += 1;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ilog() {
assert_eq!(ilog(0), 0);
assert_eq!(ilog(1), 1);
assert_eq!(ilog(2), 2);
assert_eq!(ilog(3), 2);
assert_eq!(ilog(4), 3);
assert_eq!(ilog(7), 3);
assert_eq!(ilog(8), 4);
assert_eq!(ilog(255), 8);
assert_eq!(ilog(256), 9);
}
#[test]
fn test_book_map_type1_quantvals() {
assert_eq!(book_map_type1_quantvals(8, 2), 2); assert_eq!(book_map_type1_quantvals(27, 3), 3); assert_eq!(book_map_type1_quantvals(16, 2), 4); assert_eq!(book_map_type1_quantvals(9, 2), 3); assert_eq!(book_map_type1_quantvals(1, 1), 1); }
}