-
Notifications
You must be signed in to change notification settings - Fork 37
/
Clz.hpp
37 lines (35 loc) · 795 Bytes
/
Clz.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#pragma once
#include <cassert>
#include <cstdint>
#ifdef _MSC_VER
#include <intrin.h>
static inline uint32_t clz(uint32_t x) {
assert(x != 0);
unsigned long leading_zero;
_BitScanReverse(&leading_zero, x);
return 31u - leading_zero;
}
#elif (defined(__GNUC__) || defined(__clang__))
static inline uint32_t clz(uint32_t x) {
assert(x != 0);
return __builtin_clz(x);
}
#else
static inline uint32_t popcnt(uint32_t x) {
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return x & 0x0000003f;
}
static inline uint32_t clz(uint32_t x) {
assert(x != 0);
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return 32u - popcnt(x);
}
#endif