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
//! This modules implements some math helper functions.
/// Returns ceil(log2(d)) but panics if d = 0.
pub fn ceil_log2(d: usize) -> usize {
// NOTE: should this really be usize, since usize is depended on the underlying system architecture?
assert!(d != 0);
let mut pow2 = 1;
let mut ceil_log2 = 0;
while d > pow2 {
ceil_log2 += 1;
pow2 = match pow2.checked_mul(2) {
Some(x) => x,
None => break,
}
}
ceil_log2
}
/// This function is bound to be stable soon. See <https://github.com/rust-lang/rust/issues/88581>
pub fn div_ceil(a: usize, b: usize) -> usize {
(a + b - 1) / b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_log2() {
let tests = [
(1, 0),
(2, 1),
(3, 2),
(9, 4),
(15, 4),
(15430, 14),
(usize::MAX, 64),
];
for (d, expected_res) in tests.iter() {
let res = ceil_log2(*d);
println!("ceil(log2({d})) = {res}, expected = {expected_res}");
assert!(res == *expected_res)
}
}
}