How to set, clear, and toggle a single bit
bit-manipulation, bitwise-operators, c, c++
Solution
Setting a bit
Use the bitwise OR operator (`|`) to set `n`th bit of `number` to `1`.
// Can be whatever unsigned integer type you want, but
// it's important to use the same type everywhere to avoid
// performance issues caused by mixing integer types.
typedef unsigned long Uint;
// In C++, this can be template.
// In C11, you can make it generic with _Generic, or with macros prior to C11.
inline Uint bit_set(Uint number, Uint n) {
return number | ((Uint)1 << n);
}
Note that it's undefined behavior to shift by more than the width of a `Uint`. The same applies to all remaining examples.
Clearing a bit
Use the bitwise AND operator (`&`) to set the `n`th bit of `number` to `0`.
inline Uint bit_clear(Uint number, Uint n) {
return number & ~((Uint)1 << n);
}
You must invert the bit string with the bitwise NOT operator (`~`), then AND it.
Toggling a bit
Use the bitwise XOR operator (`^`) to toggle the `n`th bit of `number`.
inline Uint bit_toggle(Uint number, Uint n) {
return number ^ ((Uint)1 << n);
}
Checking a bit
You didn't ask for this, but I might as well add it.
To check a bit, shift `number` `n` to the right, then bitwise AND it:
// bool requires #include <stdbool.h> prior to C23
inline bool bit_check(Uint number, Uint n) {
return (number >> n) & (Uint)1;
}
Changing the nth bit to x
There are alternatives with worse codegen, but the best way is to clear the bit like in `bit_clear`, then set the bit to value, similar to `bit_set`.
inline Uint bit_set_to(Uint number, Uint n, bool x) {
return (number & ~((Uint)1 << n)) | ((Uint)x << n);
}
All solutions have been tested to provide optimal codegen with GCC and clang. See https://godbolt.org/z/Wfzh8xsjW.
Problem
How can I set, clear, and toggle a bit?
Related problems
- Why is processing a sorted array faster than processing an unsorted array?
- How do you set only certain bits of a byte in C without affecting the rest?
- How to replace bits in a bitfield without affecting other bits using C
- What are bitwise shift (bit-shift) operators and how do they work?
- How exactly do partial registers on Haswell/Skylake perform? Writing AL seems to have a false dependency on RAX, and AH is inconsistent