The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
math.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2.1 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  */
17 
18 /** Various miscellaneous utility functions
19  *
20  * @file src/lib/util/misc.h
21  *
22  * @copyright 2000,2006 The FreeRADIUS server project
23  */
24 RCSIDH(math_h, "$Id: ddf80a670a652654abb1bf19c867503ef3a0a911 $")
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 /** Find the highest order high bit in an unsigned 64 bit integer
31  *
32  * @return 0-64 indicating the position of the highest bit,
33  * with 0 indicating no high bits, 1 indicating the 1st
34  * bit and 64 indicating the last bit.
35  */
36 static inline uint8_t fr_high_bit_pos(uint64_t num)
37 {
38  if (num == 0) return 0; /* num being zero is undefined behaviour for __builtin_clzll */
39 
40 #ifdef HAVE_BUILTIN_CLZLL
41  return (64 - __builtin_clzll(num));
42 #else
43  uint8_t ret = 1;
44  while (num >>= 1) ret++;
45  return ret;
46 #endif
47 }
48 
49 /** Find the lowest order high bit in an unsigned 64 bit integer
50  *
51  * @return 0-64 indicating the position of the lowest bit,
52  * with 0 indicating no high bits, 1 indicating the 1st
53  * bit and 64 indicating the last bit.
54  */
55 static inline uint8_t fr_low_bit_pos(uint64_t num)
56 {
57  if (num == 0) return 0;
58 
59 #ifdef HAVE_BUILTIN_CLZLL
60  return __builtin_ctzll(num) + 1;
61 #else
62  uint8_t ret = 1;
63 
64  do {
65  if (num & 0x01) break;
66  ret++;
67  } while (num >>= 1);
68 
69  return ret;
70 #endif
71 }
72 
73 /** Efficient calculation of log10 of a unsigned 64bit integer
74  *
75  * @param[in] num to calculate log10 of.
76  * @return log10 of the integer
77  */
78 static inline uint8_t fr_log10(uint64_t num)
79 {
80  static uint64_t const pow_of_10[] =
81  {
82  1ULL,
83  10ULL,
84  100ULL,
85  1000ULL,
86  10000ULL,
87  100000ULL,
88  1000000ULL,
89  10000000ULL,
90  100000000ULL,
91  1000000000ULL,
92  10000000000ULL,
93  100000000000ULL,
94  1000000000000ULL,
95  10000000000000ULL,
96  100000000000000ULL,
97  1000000000000000ULL,
98  10000000000000000ULL,
99  100000000000000000ULL,
100  1000000000000000000ULL,
101  10000000000000000000ULL
102  };
103  uint64_t tmp;
104 
105  tmp = (fr_high_bit_pos(num) * 1233) >> 12;
106  return tmp - (num < pow_of_10[tmp]);
107 }
108 
109 /** Multiplies two integers together
110  *
111  * @param[in] _out Where to store the result.
112  * @param[in] _a first argument to multiply.
113  * @param[in] _b second argument to multiply.
114  * @return
115  * - false on overflow.
116  * - true if there was no overflow.
117  */
118 #define fr_multiply(_out, _a, _b) !__builtin_mul_overflow(_a, _b, _out)
119 
120 /** Adds two integers
121  *
122  * @param[in] _out Where to store the result.
123  * @param[in] _a first argument to add.
124  * @param[in] _b second argument to add.
125  * @return
126  * - false on overflow.
127  * - true if there was no overflow.
128  */
129 #define fr_add(_out, _a, _b) !__builtin_add_overflow(_a, _b, _out)
130 
131 /** Subtracts two integers
132  *
133  * @param[in] _out Where to store the result.
134  * @param[in] _a first argument to subtract.
135  * @param[in] _b second argument to subtract.
136  * @return
137  * - false on overflow.
138  * - true if there was no overflow.
139  */
140 #define fr_sub(_out, _a, _b) !__builtin_sub_overflow(_a, _b, _out)
141 
142 /** Round up - Only works if _mul is a power of 2 but avoids division
143  */
144 #define ROUND_UP_POW2(_num, _mul) (((_num) + ((_mul) - 1)) & ~((_mul) - 1))
145 
146 /** Round up - Works in all cases, but is slower
147  */
148 #define ROUND_UP(_num, _mul) (((((_num) + ((_mul) - 1))) / (_mul)) * (_mul))
149 
150 /** Get the ceiling value of integer division
151  *
152  */
153 #define ROUND_UP_DIV(_x, _y) (1 + (((_x) - 1) / (_y)))
154 
155 #ifdef __cplusplus
156 }
157 #endif
#define RCSIDH(h, id)
Definition: build.h:445
static uint8_t fr_low_bit_pos(uint64_t num)
Find the lowest order high bit in an unsigned 64 bit integer.
Definition: math.h:55
static uint8_t fr_log10(uint64_t num)
Efficient calculation of log10 of a unsigned 64bit integer.
Definition: math.h:78
static uint8_t fr_high_bit_pos(uint64_t num)
Find the highest order high bit in an unsigned 64 bit integer.
Definition: math.h:36
unsigned char uint8_t
Definition: merged_model.c:30