To manipulate individual bits in C++, use bitwise operators with masks. Here’s how to set, clear, and toggle a specific bit:
1. Set a Bit
Use the bitwise OR operator (|=
) to set the n
-th bit (0-based index):
int num = 5; // Binary: 0101
num |= (1 << 2); // Set bit 2 (result: 0111 → 7)
2. Clear a Bit
Use the bitwise AND operator (&=
) with a negated mask to clear the n
-th bit:
int num = 7; // Binary: 0111
num &= ~(1 << 1); // Clear bit 1 (result: 0101 → 5)
3. Toggle a Bit
Use the bitwise XOR operator (^=
) to flip the n
-th bit:
int num = 5; // Binary: 0101
num ^= (1 << 0); // Toggle bit 0 (result: 0100 → 4)
Helper Functions/Macros
Using Macros (Avoid for complex code):
#define SET_BIT(var, bit) ((var) |= (1 << (bit)))
#define CLEAR_BIT(var, bit) ((var) &= ~(1 << (bit)))
#define TOGGLE_BIT(var, bit) ((var) ^= (1 << (bit)))
Using Type-Safe Functions:
template<typename T>
void set_bit(T &var, int bit) {
static_assert(std::is_integral<T>::value, "Integral required.");
var |= (T{1} << bit);
}
template<typename T>
void clear_bit(T &var, int bit) {
static_assert(std::is_integral<T>::value, "Integral required.");
var &= ~(T{1} << bit);
}
template<typename T>
void toggle_bit(T &var, int bit) {
static_assert(std::is_integral<T>::value, "Integral required.");
var ^= (T{1} << bit);
}
Key Notes
- Bit Indexing: Bits are 0-indexed (e.g., bit 0 is the least significant bit).
- Data Types: Works with integral types (
int
,char
,uint32_t
, etc.). - Safety:
- Ensure
bit
is within the range of the type (e.g.,bit < 32
for 32-bit integers). - Prefer unsigned types to avoid sign bit issues.
- Avoid Undefined Behavior: Don’t shift beyond the type’s width (e.g.,
1 << 32
forint32_t
).
Example Outputs
Operation | Value Before | Value After | Binary Before | Binary After |
---|---|---|---|---|
Set bit 2 | 5 (0101) | 7 (0111) | 0b0101 | 0b0111 |
Clear bit 1 | 7 (0111) | 5 (0101) | 0b0111 | 0b0101 |
Toggle bit 0 | 5 (0101) | 4 (0100) | 0b0101 | 0b0100 |
By using these operations, you can efficiently manipulate individual bits in C++.