JayBeams  0.1
Another project to have fun coding.
p2ceil.hpp
Go to the documentation of this file.
1 #ifndef jb_p2ceil_hpp
2 #define jb_p2ceil_hpp
3 
4 #include <cstdint>
5 #include <type_traits>
6 
7 namespace jb {
8 
9 /**
10  * Implement the key operation in the p2ceil() function.
11  *
12  * The p2ceil() functions are implemented as a series of recursive
13  * calls to this function.
14  *
15  * @tparam T the type of the input, must be an integer type.
16  */
17 template <typename T>
18 constexpr T p2ceil_kernel(int shift, T n) {
19  static_assert(
20  std::is_integral<T>::value, "p2ceil_kernel input type must be integral");
21  return n | (n >> shift);
22 }
23 
24 /**
25  * Find the smallest power of 2 larger than n for a 64-bit integer.
26  *
27  * The algorithm can be executed at compile time, so it is suitable
28  * for use in template expressions. The algorithm first computes all
29  * the
30  *
31  * @param n the input number, must be smaller or equal to 2^63.
32  * @returns the smallest power of two larger than @a n.
33  */
34 constexpr std::uint64_t p2ceil(std::uint64_t n) {
35  // Picture the bitwise representation of the number. Let {b} be the
36  // highest bit set on the number. If we compute:
37  // n1 = n | n >> 1;
38  // we have a number where (at least), {b} and {b-1} are set. After
39  // computing this, we can compute:
40  // n2 = n1 | n1 >> 2;
41  // to obtain a number where at least {b} through {b-3} are set.
42  //
43  // We can repeatedly apply this operation with a 4-shift, 8-shift,
44  // 16-shift and 32-shift to obtain a number where all the bits from
45  // {b} to 0 are set. That number is equal to 2^{b+1}-1, so adding 1
46  // to this number is exactly what we need.
47  //
48  // Because we are performing this operations in a constexpr (under
49  // C++11), we cannot use intermediate variables, but we can use
50  // recursive calls to other constexpr functions:
51  return 1 +
53  32,
55  16, p2ceil_kernel(
56  8, p2ceil_kernel(
57  4, p2ceil_kernel(2, p2ceil_kernel(1, n))))));
58 }
59 
60 /**
61  * Find the smallest power of 2 larger than n for a 32-bit integer.
62  *
63  * @param n the input number, must be smaller or equal to 2^31.
64  * @returns the smallest power of two larger than @a n.
65  */
66 constexpr std::uint32_t p2ceil(std::uint32_t n) {
67  return 1 +
69  16,
71  8, p2ceil_kernel(4, p2ceil_kernel(2, p2ceil_kernel(1, n)))));
72 }
73 
74 /**
75  * Find the smallest power of 2 larger than n for a 16-bit integer.
76  *
77  * @param n the input number, must be smaller or equal to 2^15.
78  * @returns the smallest power of two larger than @a n.
79  */
80 constexpr std::uint16_t p2ceil(std::uint16_t n) {
81  return 1 + p2ceil_kernel(
82  8, p2ceil_kernel(4, p2ceil_kernel(2, p2ceil_kernel(1, n))));
83 }
84 
85 /**
86  * Find the smallest power of 2 larger than n for an 8-bit integer.
87  *
88  * @param n the input number, must be smaller or equal to 2^7.
89  * @returns the smallest power of two larger than @a n.
90  */
91 constexpr std::uint8_t p2ceil(std::uint8_t n) {
92  return 1 + p2ceil_kernel(4, p2ceil_kernel(2, p2ceil_kernel(1, n)));
93 }
94 
95 } // namespace jb
96 
97 #endif /* jb_p2ceil_hpp */
constexpr std::uint64_t p2ceil(std::uint64_t n)
Find the smallest power of 2 larger than n for a 64-bit integer.
Definition: p2ceil.hpp:34
constexpr T p2ceil_kernel(int shift, T n)
Implement the key operation in the p2ceil() function.
Definition: p2ceil.hpp:18
The top-level namespace for the JayBeams library.
Definition: as_hhmmss.hpp:7