algorithms_edu/algo/math/
log2.rs

1use num_traits::PrimInt;
2
3pub trait IntLog2: PrimInt {
4    fn log2(self) -> Self {
5        Self::from(8 * std::mem::size_of::<Self>() - (self.leading_zeros() as usize) - 1).unwrap()
6    }
7}
8
9impl<I: PrimInt> IntLog2 for I {}
10
11pub trait VecLog2 {
12    fn log2(n: usize) -> Self;
13}
14
15impl<I: PrimInt> VecLog2 for Vec<I> {
16    fn log2(n: usize) -> Vec<I> {
17        let mut log2 = vec![I::zero(); n];
18        for i in 2..n {
19            log2[i] = log2[i / 2] + I::one();
20        }
21        log2
22    }
23}
24
25#[cfg(test)]
26mod tests {
27    use super::*;
28    #[test]
29    fn test_log2() {
30        assert_eq!(0x10u8.log2(), 4);
31        assert_eq!(0x0111u16.log2(), 8);
32        assert_eq!(0x0101i32.log2(), 8);
33    }
34
35    #[test]
36    fn test_log2_vec() {
37        let log2 = Vec::<i128>::log2(17);
38        let expected = &[0i128, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4];
39        assert_eq!(&log2, expected);
40    }
41}