The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
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 */
24RCSIDH(math_h, "$Id: ddf80a670a652654abb1bf19c867503ef3a0a911 $")
25
26#ifdef __cplusplus
27extern "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 */
36static 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 */
55static 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 */
78static 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:484
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