17 inline double log2 (
double x) {
24 inline uint32_t log2_lsb(
const T& x)
28 throw SpartaException(
"Unsupported type for log2_lsb: ") <<
typeid(T).name();
32 inline uint32_t log2_lsb<uint32_t>(
const uint32_t &x)
38 static const uint32_t index32[32] = {
39 0, 1, 28, 2, 29, 14, 24, 3,
40 30, 22, 20, 15, 25, 17, 4, 8,
41 31, 27, 13, 23, 21, 19, 16, 7,
42 26, 12, 18, 6, 11, 5, 10, 9
45 static const uint32_t debruijn32 = 0x077CB531u;
47 return index32[((x & -x) * debruijn32) >> 27];
51 inline uint32_t log2_lsb<uint64_t>(
const uint64_t &x)
57 static const uint32_t index64[64] = {
58 63, 0, 58, 1, 59, 47, 53, 2,
59 60, 39, 48, 27, 54, 33, 42, 3,
60 61, 51, 37, 40, 49, 18, 28, 20,
61 55, 30, 34, 11, 43, 14, 22, 4,
62 62, 57, 46, 52, 38, 26, 32, 41,
63 50, 36, 17, 19, 29, 10, 13, 21,
64 56, 45, 25, 31, 35, 16, 9, 12,
65 44, 24, 15, 8, 23, 7, 6, 5
68 static const uint64_t debruijn64 = 0x07EDD5E59A4E28C2ull;
70 return index64[((x & -x) * debruijn64) >> 58];
74 inline uint64_t floor_log2(T x)
88 inline uint64_t floor_log2<double>(
double x)
90 return std::floor(log2(x));
94 inline uint64_t floor_log2<uint32_t>(uint32_t x)
105 static const uint64_t lut[] = {
106 0, 9, 1, 10, 13, 21, 2, 29,
107 11, 14, 16, 18, 22, 25, 3, 30,
108 8, 12, 20, 28, 15, 17, 24, 7,
109 19, 27, 23, 6, 26, 5, 4, 31};
116 return lut[(uint32_t)(x * 0x07C4ACDDul) >> 27];
120 inline uint64_t floor_log2<uint64_t>(uint64_t x)
131 static const uint64_t lut[] = {
132 63, 0, 58, 1, 59, 47, 53, 2,
133 60, 39, 48, 27, 54, 33, 42, 3,
134 61, 51, 37, 40, 49, 18, 28, 20,
135 55, 30, 34, 11, 43, 14, 22, 4,
136 62, 57, 46, 52, 38, 26, 32, 41,
137 50, 36, 17, 19, 29, 10, 13, 21,
138 56, 45, 25, 31, 35, 16, 9, 12,
139 44, 24, 15, 8, 23, 7, 6, 5};
147 return lut[((uint64_t)((x - (x >> 1)) * 0x07EDD5E59A4E28C2ull)) >> 58];
150 inline uint64_t ceil_log2 (uint64_t x)
154 uint64_t y = floor_log2(x);
155 if ((
static_cast<uint64_t
>(1) << y) != x) {
161 inline uint64_t pow2 (uint64_t x) {
162 uint64_t y =
static_cast<uint64_t
>(1) << x;
166 inline bool is_power_of_2 (uint64_t x) {
167 bool y = x && !(x & (x - 1));
171 inline uint64_t next_power_of_2(uint64_t v)
176 return 1ull << ((
sizeof(uint64_t) * 8) - __builtin_clzll(v - 1ull));
179 inline uint64_t ones (uint64_t x) {
180 uint64_t y = (
static_cast<uint64_t
>(1) << x) - 1;
192 return (x < 0 ? -x : x);
196 inline uint8_t abs<uint8_t>(uint8_t x) {
197 uint8_t sign_mask = int8_t(x) >> 7;
198 return (x + sign_mask) ^ sign_mask;
202 inline uint16_t abs<uint16_t>(uint16_t x) {
203 uint16_t sign_mask = int16_t(x) >> 15;
204 return (x + sign_mask) ^ sign_mask;
208 inline uint32_t abs<uint32_t>(uint32_t x) {
209 uint32_t sign_mask = int32_t(x) >> 31;
210 return (x + sign_mask) ^ sign_mask;
214 inline uint64_t abs<uint64_t>(uint64_t x) {
215 uint64_t sign_mask = int64_t(x) >> 63;
216 return (x + sign_mask) ^ sign_mask;
220 inline T gcd(T u, T v)
224 static_assert(
"This is an unsupported type");
229 inline uint32_t gcd<uint32_t>(uint32_t u, uint32_t v)
232 if (u == 0 || v == 0)
237 uint32_t shift = log2_lsb(u | v);
264 inline uint64_t gcd<uint64_t>(uint64_t u, uint64_t v)
267 if (u == 0 || v == 0)
272 uint32_t shift = log2_lsb(u | v);
298 inline T lcm(
const T& u,
const T& v)
303 throw SpartaException(
"Unsupported type for lcm: ") <<
typeid(T).name();
307 inline uint32_t lcm<uint32_t>(
const uint32_t &u,
const uint32_t &v)
315 return u / gcd(u, v) * v;
320 inline uint64_t lcm<uint64_t>(
const uint64_t &u,
const uint64_t &v)
328 return u / gcd(u, v) * v;
336 static_assert(std::is_integral<T>::value,
"sparta::safe_power only supports integer data types");
342 for (T x = 1; x < e; x++)
344 T old_result = result;
346 if (old_result > result)
348 throw SpartaException(
"power() overflowed!");
Set of macros for Sparta assertions. Caught by the framework.
Exception class for all of Sparta.
Macros for handling exponential backoff.