competitive_hpp/utils/
math.rs

1pub trait MathUtils {
2    /// ## Example:
3    /// ```
4    /// use competitive_hpp::prelude::*;
5    ///
6    /// assert_eq!(16.log2_trunc(), 4);
7    /// assert_eq!(10.log2_trunc(), 3);
8    /// ```
9    fn log2_trunc(self) -> Self;
10    fn sqrt_floor(self) -> Self;
11    fn sqrt_ceil(self) -> Self;
12}
13
14macro_rules! impl_digit_utils(($($ty:ty),*) => {
15    $(
16        impl MathUtils for $ty {
17            #[inline]
18            fn log2_trunc(self) -> Self {
19                (self as f64).log2().trunc() as Self
20            }
21
22            #[inline]
23            fn sqrt_floor(self) -> Self {
24                (self as f64).sqrt() as Self
25            }
26
27            #[inline]
28            fn sqrt_ceil(self) -> Self {
29                let tmp = (self as f64).sqrt() as Self;
30                if tmp * tmp == self {
31                    tmp
32                } else {
33                    tmp + 1
34                }
35            }
36        }
37    )*
38});
39
40impl_digit_utils!(u64, u32, i64, i32, usize, isize);
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    macro_rules! impl_math_tests (($ty:ty) => {
47        assert_eq!((16 as $ty).log2_trunc(), 4);
48        assert_eq!((10 as $ty).log2_trunc(), 3);
49
50        assert_eq!((9 as $ty).sqrt_floor(), 3);
51        assert_eq!((10 as $ty).sqrt_floor(), 3);
52        assert_eq!((15 as $ty).sqrt_floor(), 3);
53
54        assert_eq!((9 as $ty).sqrt_ceil(), 3);
55        assert_eq!((10 as $ty).sqrt_ceil(), 4);
56        assert_eq!((10 as $ty).sqrt_ceil(), 4);
57
58    });
59
60    #[test]
61    fn u64_math_test() {
62        impl_math_tests!(u64);
63    }
64    #[test]
65    fn u32_math_test() {
66        impl_math_tests!(u32);
67    }
68    #[test]
69    fn i64_math_test() {
70        impl_math_tests!(i64);
71    }
72    #[test]
73    fn i32_math_test() {
74        impl_math_tests!(i32);
75    }
76    #[test]
77    fn usize_math_test() {
78        impl_math_tests!(usize);
79    }
80    #[test]
81    fn isize_math_test() {
82        impl_math_tests!(isize);
83    }
84}