AFBR-S50 API Reference Manual  v1.6.5
AFBR-S50 Time-of-Flight Sensor SDK for Embedded Software
int_math.h
Go to the documentation of this file.
1 /*************************************************************************/
37 #ifndef INT_MATH
38 #define INT_MATH
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /*!***************************************************************************
44  * @addtogroup argus_misc
45  * @{
46  *****************************************************************************/
47 
48 #include <stdint.h>
49 #include <assert.h>
50 
52 #ifndef INT_SQRT
53 #define INT_SQRT 0
54 #endif
55 
56 /*!***************************************************************************
57  * @brief Integer Base-2 Logarithm.
58  *
59  * @details Calculates the base-2 logarithm for unsigned integer values. The
60  * result is the integer equivalent of floor(log2(x)).
61  *
62  * @param x Input parameter.
63  * @return The floor of the base-2 logarithm.
64  *****************************************************************************/
65 inline uint32_t log2i(uint32_t x)
66 {
67  assert(x != 0);
68 #if 1
69  return (uint32_t)(31 - __builtin_clz(x));
70 #else
71  #define S(k) if (x >= (1 << k)) { i += k; x >>= k; }
72  int i = 0; S(16); S(8); S(4); S(2); S(1); return i;
73  #undef S
74 #endif
75 }
76 
77 /*!***************************************************************************
78  * @brief Integer Base-2 Logarithm with rounded result.
79  *
80  * @details Calculates the base-2 logarithm for unsigned integer values and
81  * returns the rounded result. The result is the integer equivalent
82  * of round(log2(x)).
83  *
84  * It is finding the nearest power-of-two value s.t. |x - 2^n| becomes
85  * minimum for all n.
86  *
87  * @param x Input parameter.
88  * @return The rounded value of the base-2 logarithm.
89  *****************************************************************************/
90 inline uint32_t log2_round(uint32_t x)
91 {
92  assert(x != 0);
93 #if 0
94  const uint32_t y = x;
95  const uint32_t i = 0;
96  while (y >>= 1) i++;
97 #else
98  const uint32_t i = log2i(x);
99 #endif
100  return (i + ((x >> (i - 1U)) == 3U));
101 }
102 
103 /*!***************************************************************************
104  * @brief Finding the nearest power-of-two value.
105  *
106  * @details Implemented s.t. |x - 2^n| becomes minimum for all n.
107  * Special case 0: returns 0;
108  * Maximum input: 3037000499; higher number result in overflow! (returns 0)
109  *
110  * @param x Input parameter.
111  * @return Nearest power-of-two number, i.e. 2^n.
112  *****************************************************************************/
113 inline uint32_t binary_round(uint32_t x)
114 {
115  assert(x != 0);
116  const uint32_t shift = log2_round(x);
117  return (shift > 31U) ? 0 : 1U << shift;
118 }
119 
120 /*!***************************************************************************
121  * @brief Counting bits set in a 32-bit unsigned integer.
122  *
123  * @details @see http://graphics.stanford.edu/~seander/bithacks.html
124  *
125  * @param x Input parameter.
126  * @return Number of bits set in input value.
127  *****************************************************************************/
128 inline uint32_t popcount(uint32_t x)
129 {
130  // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
131  x = x - ((x >> 1) & 0x55555555);
132  x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
133  return (((x + (x >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
134 }
135 
136 /*!***************************************************************************
137  * @brief Determining if an integer is a power of 2
138  *
139  * @details @see http://graphics.stanford.edu/~seander/bithacks.html
140  *
141  * @param x Input parameter.
142  * @return True if integer is power of 2.
143  *****************************************************************************/
144 inline uint32_t ispowoftwo(uint32_t x)
145 {
146  return x && !(x & (x - 1));
147 }
148 
149 /*!***************************************************************************
150  * @brief Calculates the absolute value.
151  *
152  * @param x Input parameter.
153  * @return The absolute value of x.
154  *****************************************************************************/
155 inline uint32_t absval(int32_t x)
156 {
157  // Note: special case of INT32_MIN must be handled correctly:
158  return x < 0 ? ((~(uint32_t)(x)) + 1) : (uint32_t)x;
159 
160  /* alternative with equal performance:*/
161 // int32_t y = x >> 31;
162 // return (x ^ y) - y;
163  /* wrong implementation:
164  * does not correctly return abs(INT32_MIN) on 32-bit platform */
165 // return x < 0 ? (uint32_t)(-x) : (uint32_t)x;
166 }
167 
168 /*!***************************************************************************
169  * @brief Calculates the floor division by a factor of 2: floor(x / 2^n).
170  *
171  * @param x Input parameter.
172  * @param n The shift value, maximum is 31.
173  * @return The floor division by 2^n result.
174  *****************************************************************************/
175 inline uint32_t floor2(uint32_t x, uint_fast8_t n)
176 {
177  assert(n < 32);
178  return x >> n;
179 }
180 
181 /*!***************************************************************************
182  * @brief Calculates the ceildiv division by a factor of 2: ceildiv(x / 2^n).
183  *
184  * @param x Input parameter.
185  * @param n The shift value, maximum is 31.
186  * @return The ceildiv division by 2^n result.
187  *****************************************************************************/
188 inline uint32_t ceiling2(uint32_t x, uint_fast8_t n)
189 {
190  assert(n < 32);
191  return x ? (1 + ((x - 1) >> n)) : 0;
192 }
193 
194 /*!***************************************************************************
195  * @brief Calculates the ceildiv division: ceildiv(x / y).
196  *
197  * @param x Numerator
198  * @param y Denominator
199  * @return The result of the ceildiv division ceildiv(x / y).
200  *****************************************************************************/
201 inline uint32_t ceildiv(uint32_t x, uint32_t y)
202 {
203  assert(y != 0);
204  return x ? (1 + ((x - 1) / y)) : 0;
205 }
206 
207 /*!***************************************************************************
208  * @brief Calculates the maximum of two values.
209  *
210  * @param a Input parameter.
211  * @param b Input parameter.
212  * @return The maximum value of the input parameters.
213  *****************************************************************************/
214 #define MAX(a, b) ((a) > (b) ? (a) : (b))
215 
216 /*!***************************************************************************
217  * @brief Calculates the minimum of two values.
218  *
219  * @param a Input parameter.
220  * @param b Input parameter.
221  * @return The minimum value of the input parameters.
222  *****************************************************************************/
223 #define MIN(a, b) ((a) < (b) ? (a) : (b))
224 
225 /*!***************************************************************************
226  * @brief Clamps a value between a minimum and maximum boundary.
227  *
228  * @details Clamps the values such that the condition min <= x <= max is true.
229  *
230  * @note The condition \p min <= \p max must hold!!!
231  *
232  * @param x The input parameter to be clamped.
233  * @param min The minimum or lower boundary.
234  * @param max The maximum or upper boundary.
235  * @return The clamped value of the input parameter within [min,max].
236  *****************************************************************************/
237 #define CLAMP(x, min, max) (MIN(MAX((x), (min)), (max)))
238 
239 #if INT_SQRT
240 /*!***************************************************************************
241  * @brief Calculates the integer square root of x.
242  *
243  * @details The integer square root is defined as:
244  * isqrt(x) = (int)sqrt(x)
245  *
246  * @see https://en.wikipedia.org/wiki/Integer_square_root
247  * @see https://github.com/chmike/fpsqrt/blob/master/fpsqrt.c
248  *
249  * @param x Input parameter.
250  * @return isqrt(x)
251  *****************************************************************************/
252 inline uint32_t isqrt(uint32_t v)
253 {
254  unsigned t, q, b, r;
255  r = v; // r = v - x²
256  b = 0x40000000; // a²
257  q = 0; // 2ax
258 
259  while( b > 0 )
260  {
261  t = q + b; // t = 2ax + a²
262  q >>= 1; // if a' = a/2, then q' = q/2
263  if( r >= t ) // if (v - x²) >= 2ax + a²
264  {
265  r -= t; // r' = (v - x²) - (2ax + a²)
266  q += b; // if x' = (x + a) then ax' = ax + a², thus q' = q' + b
267  }
268  b >>= 2; // if a' = a/2, then b' = b / 4
269  }
270  return q;
271 }
272 #endif // INT_SQRT
273 
275 #ifdef __cplusplus
276 } // extern "C"
277 #endif
278 #endif /* INT_MATH */
ceiling2
uint32_t ceiling2(uint32_t x, uint_fast8_t n)
Calculates the ceildiv division by a factor of 2: ceildiv(x / 2^n).
Definition: int_math.h:188
log2_round
uint32_t log2_round(uint32_t x)
Integer Base-2 Logarithm with rounded result.
Definition: int_math.h:90
ceildiv
uint32_t ceildiv(uint32_t x, uint32_t y)
Calculates the ceildiv division: ceildiv(x / y).
Definition: int_math.h:201
ispowoftwo
uint32_t ispowoftwo(uint32_t x)
Determining if an integer is a power of 2.
Definition: int_math.h:144
log2i
uint32_t log2i(uint32_t x)
Integer Base-2 Logarithm.
Definition: int_math.h:65
floor2
uint32_t floor2(uint32_t x, uint_fast8_t n)
Calculates the floor division by a factor of 2: floor(x / 2^n).
Definition: int_math.h:175
popcount
uint32_t popcount(uint32_t x)
Counting bits set in a 32-bit unsigned integer.
Definition: int_math.h:128
binary_round
uint32_t binary_round(uint32_t x)
Finding the nearest power-of-two value.
Definition: int_math.h:113
absval
uint32_t absval(int32_t x)
Calculates the absolute value.
Definition: int_math.h:155