Bitwise operators
AND, OR, XOR and shifts, and packing flags into one number.
| Operator | Meaning |
|---|---|
a & b | AND: 1 only where both bits are 1 |
a | b | OR: 1 where either bit is 1 |
a ^ b | XOR: 1 where the bits differ |
~a | NOT: flip every bit |
a << n | Shift left: multiply by 2ⁿ |
a >> n | Shift right: divide by 2ⁿ |
C
#include <stdio.h>
int main(void) {
unsigned int a = 12, b = 10; /* 1100 and 1010 in binary */
printf("%u %u %u\n", a & b, a | b, a ^ b);
printf("%u %u\n", a << 1, a >> 2);
int n = 7;
printf("%s\n", (n & 1) ? "odd" : "even");
unsigned int x = 29; /* 11101 */
int bits = 0;
while (x != 0) {
x &= x - 1; /* clears the lowest 1 bit */
bits++;
}
printf("%d\n", bits);
unsigned int v = 64;
printf("%d\n", v != 0 && (v & (v - 1)) == 0); /* power of two? */
return 0;
}Output
8 14 6 24 3 odd 4 1
These tricks come up often in placement tests: n & 1 tests for odd, x & (x - 1) clears the lowest set bit, and a power of two has exactly one bit set.
Flags in one number
C
#include <stdio.h>
enum { CAN_READ = 1 << 0, CAN_WRITE = 1 << 1, CAN_DELETE = 1 << 2 };
int main(void) {
unsigned int role = CAN_READ | CAN_WRITE;
printf("%d\n", (role & CAN_WRITE) != 0);
role &= ~CAN_WRITE;
printf("%d\n", (role & CAN_WRITE) != 0);
role |= CAN_DELETE;
printf("%u\n", role);
return 0;
}Output
1 0 5
Device firmware and permission systems pack many on/off switches into one integer like this. Use unsigned types for bit work, because shifting negative numbers is not well defined in C.