C23 stdbit.h quick reference
Macros | Implementation |
---|---|
#define __STDC_ENDIAN_LITTLE__ | Some integer constant |
#define __STDC_ENDIAN_BIG__ | Some integer constant |
#define __STDC_ENDIAN_NATIVE__ | __STDC_ENDIAN_LITTLE__ or__STDC_ENDIAN_BIG__ (†) |
Regular functions | Implementation |
unsigned stdc_leading_zeros(T x) | lzcnt(x) |
unsigned stdc_first_leading_one(T x) | x ? lzcnt(x) + 1 : 0 |
unsigned stdc_trailing_zeros(T x) | tzcnt(x) |
unsigned stdc_first_trailing_one(T x) | x ? tzcnt(x) + 1 : 0 |
unsigned stdc_count_ones(T x) | popcnt(x) |
bool stdc_has_single_bit(T x) | popcnt(x) == 1 |
unsigned stdc_bit_width(T x) | x ? floor(log2(x)) + 1 : 0 |
T stdc_bit_floor(T x) | x ? (T)1 << floor(log2(x)) : 0 |
T stdc_bit_ceil(T x) | x ? (T)1 << ceil(log2(x)) : 1 (‡) |
Inverted functions | Implementation |
unsigned stdc_leading_ones(T x) | lzcnt((T)~x) |
unsigned stdc_first_leading_zero(T x) | (T)~x ? lzcnt((T)~x) + 1 : 0 |
unsigned stdc_trailing_ones(T x) | tzcnt((T)~x) |
unsigned stdc_first_trailing_zero(T x) | (T)~x ? tzcnt((T)~x) + 1 : 0 |
unsigned stdc_count_zeros(T x) | popcnt((T)~x) |
(†) Or some third value if the execution environment is neither little endian nor big endian.
(‡) Undefined if the <<
overflows or if the result does not fit in T
.
Where:
T
denotes eitherunsigned char
orunsigned short
orunsigned int
orunsigned long
orunsigned long long
. Each function takingT
is type-generic, dispatching to one of these five variants. The individual variants are also available by appending a_uc
or_us
or_ui
or_ul
or_ull
suffix to the function name. Implementations might also supportuint128_t
.lzcnt
returns the number of leading zero bits. For an input of zero, this issizeof(T) * CHAR_BIT
.tzcnt
returns the number of trailing zero bits. For an input of zero, this issizeof(T) * CHAR_BIT
.popcnt
returns the number of set bits. For an input with all bits set, this issizeof(T) * CHAR_BIT
.log2(0)
is undefined,log2
coincides withtzcnt
for inputs that are powers of two, and otherwiselog2
is strictly monotonic and returns a float.
The inverted functions can all be implemented by inverting the input and then passing it to one of the regular functions.
The stdc_first_leading_
functions are slightly slippery, and require a careful reading of the standard. For example, stdc_first_leading_one
is defined as:
Returns the most significant index of the first 1 bit in
value
, plus 1. If it is not found, this function returns0
.
In turn, most significant index has the following unintuitive definition:
The most significant index is the
0
-based index counting from the most significant bit,0
, to the least significant bit,w − 1
, wherew
is the width of the type that is having its most significant index computed.
The initial patches for these functions in musl got this wrong, instead using the more intuitive definition of most significant index.