Bit Manipulation
Bitwise Operators
&: AND|: OR^: XOR~: NOT<<: Binary Left Shift>>: Binary Right Shift>>>: Zero Fill Right Shift
Bit Facts & Tricks
x ^ 0s = x x & 0s = 0 x | 0s = x
x ^ 1s = ~x x & 1s = x x | 1s = 1s
x ^ x = 0 x & x = x x | x = x
Two's Complement
- Computers typically store integers in two's complement representation.
- Range of unsigned numbers that can be stored with
Nbits is0-+(2^N - 1). - Range of signed numbers that can be stored with
Nbits in two's complement representation is-(2^(N - 1))-+(2^(N - 1) - 1). - Binary representation of
-Kisconcat(1, bin(2^(N - 1) - K)). Another way to compute it is to flip the bits of the binary representation ofK, add1and then prepend the sign bit1.
Arithmetic vs. Logical Shift
- In an arithmetic right shift (
>>), the bits are shifted and the sign bit is put in the MSB. - In a logical right shift (
>>>), the bits are shifted and a0is put in the MSB.
Common Bit Tasks
Get Bit
boolean getBit(int num, int i) {
return ((num & (1 << i)) != 0);
}
Set Bit
int setBit(int num, int i) {
return num | (1 << i);
}
Clear Bit(s)
int clearBit(int num, int i) {
return num & ~(1 << i);
}
int clearBitsMSBThroughI(int num, int i) {
int mask = (1 << i) - 1;
return num & mask;
}
int clearBitsIThrough0(int num, int i) {
int mask = (-1 << (i + 1));
return num & mask;
}
Toggle Bit
int toggleBit(int num, int i) {
return num ^ (1 << i);
}
Update Bit
int updateBit(int num, int i, boolean setBit) {
int value = setBit ? 1 : 0;
int mask = ~(1 << i);
return (num & mask) | (value << i);
}
Multiply/Divide by 2n
num = num << n; // multiply
num = num >> n; // divide