Botan  2.4.0
Crypto and TLS for C++11
bit_ops.h
Go to the documentation of this file.
1 /*
2 * Bit/Word Operations
3 * (C) 1999-2008 Jack Lloyd
4 * (C) Copyright Projet SECRET, INRIA, Rocquencourt
5 * (C) Bhaskar Biswas and Nicolas Sendrier
6 * (C) 2014 cryptosource GmbH
7 * (C) 2014 Falko Strenzke fstrenzke@cryptosource.de
8 *
9 * Botan is released under the Simplified BSD License (see license.txt)
10 */
11 
12 #ifndef BOTAN_BIT_OPS_H_
13 #define BOTAN_BIT_OPS_H_
14 
15 #include <botan/types.h>
16 
17 namespace Botan {
18 
19 /**
20 * Power of 2 test. T should be an unsigned integer type
21 * @param arg an integer value
22 * @return true iff arg is 2^n for some n > 0
23 */
24 template<typename T>
25 inline bool is_power_of_2(T arg)
26  {
27  return ((arg != 0 && arg != 1) && ((arg & (arg-1)) == 0));
28  }
29 
30 /**
31 * Return the index of the highest set bit
32 * T is an unsigned integer type
33 * @param n an integer value
34 * @return index of the highest set bit in n
35 */
36 template<typename T>
37 inline size_t high_bit(T n)
38  {
39  for(size_t i = 8*sizeof(T); i > 0; --i)
40  if((n >> (i - 1)) & 0x01)
41  return i;
42  return 0;
43  }
44 
45 /**
46 * Return the index of the lowest set bit
47 * T is an unsigned integer type
48 * @param n an integer value
49 * @return index of the lowest set bit in n
50 */
51 template<typename T>
52 inline size_t low_bit(T n)
53  {
54  for(size_t i = 0; i != 8*sizeof(T); ++i)
55  if((n >> i) & 0x01)
56  return (i + 1);
57  return 0;
58  }
59 
60 /**
61 * Return the number of significant bytes in n
62 * @param n an integer value
63 * @return number of significant bytes in n
64 */
65 template<typename T>
66 inline size_t significant_bytes(T n)
67  {
68  for(size_t i = 0; i != sizeof(T); ++i)
69  if(get_byte(i, n))
70  return sizeof(T)-i;
71  return 0;
72  }
73 
74 /**
75 * Compute Hamming weights
76 * @param n an integer value
77 * @return number of bits in n set to 1
78 */
79 template<typename T>
80 inline size_t hamming_weight(T n)
81  {
82  const uint8_t NIBBLE_WEIGHTS[] = {
83  0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
84 
85  size_t weight = 0;
86  for(size_t i = 0; i != 2*sizeof(T); ++i)
87  weight += NIBBLE_WEIGHTS[(n >> (4*i)) & 0x0F];
88  return weight;
89  }
90 
91 /**
92 * Count the trailing zero bits in n
93 * @param n an integer value
94 * @return maximum x st 2^x divides n
95 */
96 template<typename T>
97 inline size_t ctz(T n)
98  {
99  for(size_t i = 0; i != 8*sizeof(T); ++i)
100  if((n >> i) & 0x01)
101  return i;
102  return 8*sizeof(T);
103  }
104 
105 #if defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG)
106 
107 template<>
108 inline size_t ctz(uint32_t n)
109  {
110  return __builtin_ctz(n);
111  }
112 
113 #endif
114 
115 
116 template<typename T>
117 size_t ceil_log2(T x)
118  {
119  if(x >> (sizeof(T)*8-1))
120  return sizeof(T)*8;
121 
122  size_t result = 0;
123  T compare = 1;
124 
125  while(compare < x)
126  {
127  compare <<= 1;
128  result++;
129  }
130 
131  return result;
132  }
133 
134 }
135 
136 #endif
size_t ctz(T n)
Definition: bit_ops.h:97
size_t significant_bytes(T n)
Definition: bit_ops.h:66
size_t high_bit(T n)
Definition: bit_ops.h:37
Definition: alg_id.cpp:13
size_t ceil_log2(T x)
Definition: bit_ops.h:117
fe T
Definition: ge.cpp:37
uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:39
size_t low_bit(T n)
Definition: bit_ops.h:52
size_t hamming_weight(T n)
Definition: bit_ops.h:80
bool is_power_of_2(T arg)
Definition: bit_ops.h:25