# 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 either`unsigned char`

or`unsigned short`

or`unsigned int`

or`unsigned long`

or`unsigned long long`

. Each function taking`T`

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 support`uint128_t`

.`lzcnt`

returns the number of leading zero bits. For an input of zero, this is`sizeof(T) * CHAR_BIT`

.`tzcnt`

returns the number of trailing zero bits. For an input of zero, this is`sizeof(T) * CHAR_BIT`

.`popcnt`

returns the number of set bits. For an input with all bits set, this is`sizeof(T) * CHAR_BIT`

.`log2(0)`

is undefined,`log2`

coincides with`tzcnt`

for inputs that are powers of two, and otherwise`log2`

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 returns`0`

.

In turn, *most significant index* has the following unintuitive definition:

The

most significant indexis the`0`

-based index counting from the most significant bit,`0`

, to the least significant bit,`w − 1`

, where`w`

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*.