competitive_hpp/utils/
math.rs1pub trait MathUtils {
2 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}