AND, OR, XOR
Concept
Bitwise operators perform mathematical logic on a bit-by-bit basis. They take two numbers, line up their binary columns perfectly, and execute a logical gate down the column.
1. Bitwise AND (&)
The AND gate requires BOTH bits to be 1 to output a 1. Otherwise, it outputs 0.
1 0 1 1 (11)
& 1 1 0 0 (12)
---------
1 0 0 0 (8)
Primary Use Case (Masking): AND is used to “mask” (hide) bits. If you want to check if a specific bit is a 1, you AND it with a mask of 1.
X & 1: Checks if a number is Odd. (Odd numbers always have a1in the absolute right-most 1s column. Even numbers have a0. ANDing with1instantly isolates that column).
2. Bitwise OR (|)
The OR gate requires AT LEAST ONE bit to be 1 to output a 1.
1 0 1 1 (11)
| 1 1 0 0 (12)
---------
1 1 1 1 (15)
Primary Use Case (Setting): OR is used to forcefully turn a bit ON. If you OR a bit with 1, it becomes 1. If you OR it with 0, it stays whatever it originally was.
3. Bitwise XOR (^) (Exclusive OR)
The XOR gate requires the bits to be DIFFERENT to output a 1. If they are the same (both 1 or both 0), it outputs 0.
1 0 1 1 (11)
^ 1 1 0 0 (12)
---------
0 1 1 1 (7)
Primary Use Case (Toggling / Canceling): XOR is the most tested bitwise operator in FAANG interviews because of its magical mathematical properties:
X ^ 0 = X(XORing with 0 changes nothing).X ^ 1 = ~X(XORing with 1 flips the bit).X ^ X = 0(XORing a number against ITSELF perfectly cancels it out to Zero!).
4. Bitwise NOT (~)
The NOT gate takes a single number and simply flips every single 1 to 0, and 0 to 1.
Because it flips the Sign Bit as well, ~X mathematically equals -(X + 1).
~5 evaluates to -6.
Bitmasking (Using Bits as Arrays)
Imagine you need to track which English letters (‘a’ to ‘z’) you have seen so far in a string.
You would normally use a Hash Set (Set<string>) or a boolean array of length 26. This takes Space.
Because there are only 26 letters in the alphabet, and an Integer has 32 bits, you can use a single 32-bit Integer as a perfectly functional Hash Set! This drops the Space Complexity to pure .
// The "Hash Set" is just a single Integer variable (Starts as 000...000)
let seenLetters = 0;
// 1. Calculate the letter's index (0 to 25)
const charCode = 'c'.charCodeAt(0) - 'a'.charCodeAt(0); // 'c' is index 2
// 2. Create a "Mask" by shifting a 1 into that specific column!
// 1 << 2 creates the binary: 000...000100
const mask = 1 << charCode;
// 3. To "ADD" the letter to our Set, we use OR (|)
seenLetters = seenLetters | mask;
// 4. To "CHECK" if the letter is in our Set, we use AND (&)
if ((seenLetters & mask) !== 0) {
console.log("We have seen 'c' before!");
}
Interview Questions
Q: In JavaScript, what is the difference between && and &?
A: && is the Logical AND operator. It evaluates the “truthiness” of entire variables. true && false is false. It relies on Short-Circuit evaluation (if the left side is false, it aborts immediately).
& is the Bitwise AND operator. It evaluates the strict mathematical binary bits of two integers column by column. It does not short-circuit.
Q: How do you mathematically “Turn Off” a specific bit without touching the other bits?
A: You use an AND gate with an inverted mask! If you want to turn off the 3rd bit, you create a mask with a 1 in the 3rd column (mask = 1 << 3 -> 00001000). You invert the mask using NOT (~mask -> 11110111). You then AND it with the original number (X & ~mask). Every column that aligns with a 1 remains unchanged, but the 3rd column aligns with the 0 and is permanently wiped out!