Bitwise Operators: Masks and Individual Bits
Store several small flags in one integer
A small school device represents permissions using bits: bit value 1 allows reading, 2 allows editing and 4 allows publishing. A value of 3 includes read and edit because 3 is binary 011.
Bitwise operators work on corresponding bits of integer representations. A mask selects bit positions of interest. This is a compact representation, not a complete authorization system.
Read a mask
Connect place values 1, 2 and 4 to separate flags.
Combine and test bits
Use OR to add a flag and AND to test it.
Recognize limits
Distinguish bitwise operators from logical operators and describe JavaScript’s number conversions.
Read permission value 3 as three places
Publish bit
Place value 4 is not included.
0 × 4Edit bit
Place value 2 is included.
1 × 2Read bit
Place value 1 is included.
1 × 1 → total 3
Each operator has a per-bit rule
AND & produces a one where both input bits are one. OR | produces a one where either is one. XOR ^ produces a one where the inputs differ. NOT ~ flips bits within the representation used by the operation.
Use different powers of two for independent flags. Sharing a bit between unrelated permissions would prevent the mask from distinguishing them. A named boolean record may be clearer for ordinary application code; masks are useful when a protocol or compact format already uses bits.
Before starting, review binary place values. These examples use JavaScript; other languages can use different syntax and rules.
Add and test a publishing flag
READ | EDIT combines bit values 1 and 2, producing 3. AND with PUBLISH produces zero because that bit is absent. Comparing the result with zero turns this into an explicit boolean test.
OR with PUBLISH sets that bit, producing 7, binary 111. The final AND test is now true.
JavaScript · local teaching example
const READ = 1;
const EDIT = 2;
const PUBLISH = 4;
let permissions = READ | EDIT;
console.log(permissions);
console.log((permissions & PUBLISH) !== 0);
permissions |= PUBLISH;
console.log(permissions);
console.log((permissions & PUBLISH) !== 0);Expected output
3
false
7
trueCompare AND, OR and XOR on the same numbers
Six is binary 110 and three is 011. AND keeps their shared two’s bit, giving 010 or 2. OR keeps every bit present in either operand, giving 111 or 7. XOR keeps only differences, giving 101 or 5.
The results are integers. These operations are not the short-circuit boolean conditions && and ||.
JavaScript · local teaching example
console.log(6 & 3);
console.log(6 | 3);
console.log(6 ^ 3);Expected output
2
7
5Shifts and NOT use a defined integer width
For these small nonnegative JavaScript Number values, shifting left by one moves 001 to 010, and shifting 100 right by one gives 010. Both displayed shifts produce 2.
Number bitwise operations generally convert to signed 32-bit integers; zero-filled right shift uses an unsigned result. Flipping every bit of zero with ~ gives -1 in the signed representation, not a small positive permission mask. Python integer behavior differs.
JavaScript · local teaching example
console.log(1 << 1);
console.log(4 >> 1);
console.log(~0);Expected output
2
2
-1Apply the rule to a small change
Start with all three permissions, then remove only editing. Use AND with the flipped edit mask and test whether read remains allowed.
Worked answer
The result is 5, binary 101: publishing and reading remain, editing is cleared. The named constant shows which bit is removed. XOR would toggle it, which is different from guaranteeing it is absent.
JavaScript · local teaching example
const READ = 1;
const EDIT = 2;
const PUBLISH = 4;
let permissions = READ | EDIT | PUBLISH;
permissions &= ~EDIT;
console.log(permissions);
console.log((permissions & READ) !== 0);Expected output
5
trueRecognize mistakes and limits
Do not use & in place of && to combine conditions. Bitwise operations do not provide logical short-circuit evaluation. JavaScript number operands can lose high bits during 32-bit conversion, so do not use them for arbitrary large integers.
JavaScript also supports many bitwise operations on BigInt with different width behavior, but you cannot mix Number and BigInt operands. >>> is not defined for BigInt. A permission bit pattern alone never establishes that the current user is authorized; enforce actual access rules separately.
For the language or tool rules used here, see JavaScript operator rules.
Check the core idea
JavaScript · code for this question
const READ = 1;
const EDIT = 2;
const PUBLISH = 4;
let permissions = READ | EDIT;
console.log(permissions);
console.log((permissions & PUBLISH) !== 0);
permissions |= PUBLISH;
console.log(permissions);
console.log((permissions & PUBLISH) !== 0);Apply the idea to a new situation
Use named masks and read one bit at a time
AND tests or selects bits, OR combines them, XOR toggles differences and NOT flips the representation. Shifts move bit positions. Keep JavaScript width rules and boolean logic separate.
Connect this idea with logical conditions and using a flag test in a decision.
Reaching the recap and completing the quizzes are separate milestones.