Thrill  0.1
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 <[email protected]>
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 namespace tlx {
15 
16 //! \addtogroup tlx_math
17 //! \{
18 
19 /******************************************************************************/
20 // integer_log2_floor()
21 
22 //! calculate the log2 floor of an integer type
23 template <typename IntegerType>
24 static inline unsigned integer_log2_floor_template(IntegerType i) {
25  unsigned p = 0;
26  while (i >= 65536) i >>= 16, p += 16;
27  while (i >= 256) i >>= 8, p += 8;
28  while (i >>= 1) ++p;
29  return p;
30 }
31 
32 /******************************************************************************/
33 // integer_log2_floor()
34 
35 #if defined(__GNUC__) || defined(__clang__)
36 
37 //! calculate the log2 floor of an integer type
38 static inline unsigned integer_log2_floor(int i) {
39  if (i == 0) return 0;
40  return 8 * sizeof(int) - 1 - __builtin_clz(i);
41 }
42 
43 //! calculate the log2 floor of an integer type
44 static inline unsigned integer_log2_floor(unsigned int i) {
45  if (i == 0) return 0;
46  return 8 * sizeof(unsigned) - 1 - __builtin_clz(i);
47 }
48 
49 //! calculate the log2 floor of an integer type
50 static inline unsigned integer_log2_floor(long i) {
51  if (i == 0) return 0;
52  return 8 * sizeof(long) - 1 - __builtin_clzl(i);
53 }
54 
55 //! calculate the log2 floor of an integer type
56 static inline unsigned integer_log2_floor(unsigned long i) {
57  if (i == 0) return 0;
58  return 8 * sizeof(unsigned long) - 1 - __builtin_clzl(i);
59 }
60 
61 //! calculate the log2 floor of an integer type
62 static inline unsigned integer_log2_floor(long long i) {
63  if (i == 0) return 0;
64  return 8 * sizeof(long long) - 1 - __builtin_clzll(i);
65 }
66 
67 //! calculate the log2 floor of an integer type
68 static inline unsigned integer_log2_floor(unsigned long long i) {
69  if (i == 0) return 0;
70  return 8 * sizeof(unsigned long long) - 1 - __builtin_clzll(i);
71 }
72 
73 #else
74 
75 //! calculate the log2 floor of an integer type
76 static inline unsigned integer_log2_floor(int i) {
78 }
79 
80 //! calculate the log2 floor of an integer type
81 static inline unsigned integer_log2_floor(unsigned int i) {
83 }
84 
85 //! calculate the log2 floor of an integer type
86 static inline unsigned integer_log2_floor(long i) {
88 }
89 
90 //! calculate the log2 floor of an integer type
91 static inline unsigned integer_log2_floor(unsigned long i) {
93 }
94 
95 //! calculate the log2 floor of an integer type
96 static inline unsigned integer_log2_floor(long long i) {
98 }
99 
100 //! calculate the log2 floor of an integer type
101 static inline unsigned integer_log2_floor(unsigned long long i) {
102  return integer_log2_floor_template(i);
103 }
104 
105 #endif
106 
107 /******************************************************************************/
108 // integer_log2_ceil()
109 
110 //! calculate the log2 floor of an integer type
111 static inline unsigned integer_log2_ceil(int i) {
112  if (i <= 1) return 0;
113  return integer_log2_floor(i - 1) + 1;
114 }
115 
116 //! calculate the log2 floor of an integer type
117 static inline unsigned integer_log2_ceil(unsigned int i) {
118  if (i <= 1) return 0;
119  return integer_log2_floor(i - 1) + 1;
120 }
121 
122 //! calculate the log2 floor of an integer type
123 static inline unsigned integer_log2_ceil(long i) {
124  if (i <= 1) return 0;
125  return integer_log2_floor(i - 1) + 1;
126 }
127 
128 //! calculate the log2 floor of an integer type
129 static inline unsigned integer_log2_ceil(unsigned long i) {
130  if (i <= 1) return 0;
131  return integer_log2_floor(i - 1) + 1;
132 }
133 
134 //! calculate the log2 floor of an integer type
135 static inline unsigned integer_log2_ceil(long long i) {
136  if (i <= 1) return 0;
137  return integer_log2_floor(i - 1) + 1;
138 }
139 
140 //! calculate the log2 floor of an integer type
141 static inline unsigned integer_log2_ceil(unsigned long long i) {
142  if (i <= 1) return 0;
143  return integer_log2_floor(i - 1) + 1;
144 }
145 
146 //! \}
147 
148 } // namespace tlx
149 
150 #endif // !TLX_MATH_INTEGER_LOG2_HEADER
151 
152 /******************************************************************************/
static unsigned integer_log2_floor_template(IntegerType i)
calculate the log2 floor of an integer type
static unsigned integer_log2_floor(int i)
calculate the log2 floor of an integer type
static unsigned integer_log2_ceil(int i)
calculate the log2 floor of an integer type