algorithms_edu/algo/math/
log2.rs1use 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}