Skip to content

Commit 7d1f1bb

Browse files
committed
some efficient mathematical hacks for powers of two
1 parent c9d7942 commit 7d1f1bb

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

src/cpp-utility/math/Math.hpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#pragma once
2+
3+
#include <cpp-utility/compiler/CompilerHints.hpp>
4+
5+
namespace utility::math {
6+
7+
template<typename T>
8+
forceinline constexpr bool is_power_of_two(T x) {
9+
return (x == 1) | (x && ((x & (x - 1)) == 0));
10+
}
11+
12+
template<typename T>
13+
forceinline constexpr T next_power_of_two(T value) {
14+
if (unlikely(value == 0)) {
15+
return 0;
16+
} else if (unlikely(value == 1)) {
17+
return 1;
18+
} else {
19+
if constexpr (sizeof(T) == 4) {
20+
return 1ull << ((sizeof(T) << 3) - __builtin_clz(value - 1));
21+
} else {
22+
return 1ull << ((sizeof(T) << 3) - __builtin_clzll(value - 1));
23+
}
24+
}
25+
}
26+
27+
template<typename T>
28+
forceinline constexpr T prev_power_of_two(T value) {
29+
return next_power_of_two(value) >> 1;
30+
}
31+
32+
template<typename T>
33+
forceinline constexpr T get_number_of_bits(T value) {
34+
if (value == 0) {
35+
return 0;
36+
} else if (value == 1) {
37+
return 1;
38+
} else {
39+
if constexpr (sizeof(T) == 4) {
40+
return (sizeof(T) << 3) - __builtin_clz(value - 1);
41+
} else {
42+
return (sizeof(T) << 3) - __builtin_clzll(value - 1);
43+
}
44+
}
45+
}
46+
47+
template<typename T>
48+
forceinline constexpr T align_number(const T& value, const T& align) {
49+
return ((value + align - 1) / align) * align;
50+
}
51+
52+
template<typename T>
53+
forceinline constexpr T const_log2(const T n) {
54+
return (n < 2) ? 0 : 1 + const_log2(n / 2);
55+
}
56+
57+
} // namespace utility::math

0 commit comments

Comments
 (0)