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.

  1. Read a mask

    Connect place values 1, 2 and 4 to separate flags.

  2. Combine and test bits

    Use OR to add a flag and AND to test it.

  3. Recognize limits

    Distinguish bitwise operators from logical operators and describe JavaScript’s number conversions.

Read permission value 3 as three places

  1. Publish bit

    Place value 4 is not included.

    0 × 4
  2. Edit bit

    Place value 2 is included.

    1 × 2
  3. Read bit

    Place value 1 is included.

    1 × 1 → total 3
Read these stages alongside the complete example. They explain the relationship; they do not execute code.

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
true

Compare 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
5

Shifts 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
-1

Apply 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
true

Recognize 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);
With permissions equal to 3 and PUBLISH equal to 4, why is the first publishing test false?
Choose one answer. You can try again.

Answer and explanation

The publishing bit is absent, so AND produces zero.

Yes. Binary 011 does not include place value four.

Apply the idea to a new situation

Which operation guarantees the EDIT bit is removed?
Choose one answer. You can try again.

Answer and explanation

permissions & ~EDIT

Yes. The flipped mask preserves other bits and clears EDIT.

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.

    Next lesson: Conditional Statements: Choose a Branch →