diff options
Diffstat (limited to 'include/my_bit.h')
-rw-r--r-- | include/my_bit.h | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/include/my_bit.h b/include/my_bit.h index ccdf5a069e1..ca51c9825b6 100644 --- a/include/my_bit.h +++ b/include/my_bit.h @@ -25,16 +25,50 @@ C_MODE_START extern const uchar _my_bits_reverse_table[256]; + /* - Find smallest X in 2^X >= value - This can be used to divide a number with value by doing a shift instead -*/ + my_bit_log2_xxx() + + In the given value, find the highest bit set, + which is the smallest X that satisfies the condition: (2^X >= value). + Can be used as a reverse operation for (1<<X), to find X. + + Examples: + - returns 0 for (1<<0) + - returns 1 for (1<<1) + - returns 2 for (1<<2) + - returns 2 for 3, which has (1<<2) as the highest bit set. -static inline uint my_bit_log2(ulong value) + Note, the behaviour of log2(0) is not defined. + Let's return 0 for the input 0, for the code simplicity. + See the 000x branch. It covers both (1<<0) and 0. +*/ +static inline CONSTEXPR uint my_bit_log2_hex_digit(uint8 value) { - uint bit; - for (bit=0 ; value > 1 ; value>>=1, bit++) ; - return bit; + return value & 0x0C ? /*1100*/ (value & 0x08 ? /*1000*/ 3 : /*0100*/ 2) : + /*0010*/ (value & 0x02 ? /*0010*/ 1 : /*000x*/ 0); +} +static inline CONSTEXPR uint my_bit_log2_uint8(uint8 value) +{ + return value & 0xF0 ? my_bit_log2_hex_digit(value >> 4) + 4: + my_bit_log2_hex_digit(value); +} +static inline CONSTEXPR uint my_bit_log2_uint16(uint16 value) +{ + return value & 0xFF00 ? my_bit_log2_uint8((uint8) (value >> 8)) + 8 : + my_bit_log2_uint8((uint8) value); +} +static inline CONSTEXPR uint my_bit_log2_uint32(uint32 value) +{ + return value & 0xFFFF0000UL ? + my_bit_log2_uint16((uint16) (value >> 16)) + 16 : + my_bit_log2_uint16((uint16) value); +} +static inline CONSTEXPR uint my_bit_log2_uint64(ulonglong value) +{ + return value & 0xFFFFFFFF00000000ULL ? + my_bit_log2_uint32((uint32) (value >> 32)) + 32 : + my_bit_log2_uint32((uint32) value); } |