tlx
integer_log2.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * tlx/math/integer_log2.hpp
3  *
4  * Part of tlx - http://panthema.net/tlx
5  *
6  * Copyright (C) 2007-2018 Timo Bingmann <tb@panthema.net>
7  *
8  * All rights reserved. Published under the Boost Software License, Version 1.0
9  ******************************************************************************/
10 
11 #ifndef TLX_MATH_INTEGER_LOG2_HEADER
12 #define TLX_MATH_INTEGER_LOG2_HEADER
13 
14 #include <tlx/define/constexpr.hpp>
15 
16 namespace tlx {
17 
18 //! \addtogroup tlx_math
19 //! \{
20 
21 /******************************************************************************/
22 // integer_log2_floor()
23 
24 //! calculate the log2 floor of an integer type
25 template <typename IntegerType>
26 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor_template(IntegerType i) {
27  unsigned p = 0;
28  while (i >= 65536) i >>= 16, p += 16;
29  while (i >= 256) i >>= 8, p += 8;
30  while (i >>= 1) ++p;
31  return p;
32 }
33 
34 /******************************************************************************/
35 // integer_log2_floor()
36 
37 #if defined(__GNUC__) || defined(__clang__)
38 
39 //! calculate the log2 floor of an integer type
40 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor(int i) {
41  if (i == 0) return 0;
42  return 8 * sizeof(int) - 1 - __builtin_clz(i);
43 }
44 
45 //! calculate the log2 floor of an integer type
46 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor(unsigned int i) {
47  if (i == 0) return 0;
48  return 8 * sizeof(unsigned) - 1 - __builtin_clz(i);
49 }
50 
51 //! calculate the log2 floor of an integer type
52 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor(long i) {
53  if (i == 0) return 0;
54  return 8 * sizeof(long) - 1 - __builtin_clzl(i);
55 }
56 
57 //! calculate the log2 floor of an integer type
58 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor(unsigned long i) {
59  if (i == 0) return 0;
60  return 8 * sizeof(unsigned long) - 1 - __builtin_clzl(i);
61 }
62 
63 //! calculate the log2 floor of an integer type
64 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor(long long i) {
65  if (i == 0) return 0;
66  return 8 * sizeof(long long) - 1 - __builtin_clzll(i);
67 }
68 
69 //! calculate the log2 floor of an integer type
70 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor(unsigned long long i) {
71  if (i == 0) return 0;
72  return 8 * sizeof(unsigned long long) - 1 - __builtin_clzll(i);
73 }
74 
75 #else
76 
77 //! calculate the log2 floor of an integer type
80 }
81 
82 //! calculate the log2 floor of an integer type
83 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor(unsigned int i) {
85 }
86 
87 //! calculate the log2 floor of an integer type
88 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor(long i) {
90 }
91 
92 //! calculate the log2 floor of an integer type
93 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor(unsigned long i) {
95 }
96 
97 //! calculate the log2 floor of an integer type
98 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor(long long i) {
100 }
101 
102 //! calculate the log2 floor of an integer type
103 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor(unsigned long long i) {
104  return integer_log2_floor_template(i);
105 }
106 
107 #endif
108 
109 /******************************************************************************/
110 // integer_log2_ceil()
111 
112 //! calculate the log2 floor of an integer type
114  if (i <= 1) return 0;
115  return integer_log2_floor(i - 1) + 1;
116 }
117 
118 //! calculate the log2 floor of an integer type
119 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_ceil(unsigned int i) {
120  if (i <= 1) return 0;
121  return integer_log2_floor(i - 1) + 1;
122 }
123 
124 //! calculate the log2 floor of an integer type
125 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_ceil(long i) {
126  if (i <= 1) return 0;
127  return integer_log2_floor(i - 1) + 1;
128 }
129 
130 //! calculate the log2 floor of an integer type
131 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_ceil(unsigned long i) {
132  if (i <= 1) return 0;
133  return integer_log2_floor(i - 1) + 1;
134 }
135 
136 //! calculate the log2 floor of an integer type
137 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_ceil(long long i) {
138  if (i <= 1) return 0;
139  return integer_log2_floor(i - 1) + 1;
140 }
141 
142 //! calculate the log2 floor of an integer type
143 static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_ceil(unsigned long long i) {
144  if (i <= 1) return 0;
145  return integer_log2_floor(i - 1) + 1;
146 }
147 
148 //! \}
149 
150 } // namespace tlx
151 
152 #endif // !TLX_MATH_INTEGER_LOG2_HEADER
153 
154 /******************************************************************************/
static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_ceil(int i)
calculate the log2 floor of an integer type
static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor(int i)
calculate the log2 floor of an integer type
#define TLX_ADVANCED_CONSTEXPR
Definition: constexpr.hpp:22
static TLX_ADVANCED_CONSTEXPR unsigned integer_log2_floor_template(IntegerType i)
calculate the log2 floor of an integer type