READMEJavaScript

README

Module 03 Operators / .5 Bitwise Operators

Concept Lesson
Beginner
4 min

Learning Objective

Understand Module 03 Operators well enough to explain it, recognize it in JavaScript, and apply it in a small task.

Why It Matters

This concept is part of the foundation that later lessons and projects assume you already understand.

Table Of ContentsWhat Are Bitwise OperatorsWhy Learn Bitwise OperatorsAll Bitwise OperatorsBinary Number Basics
Private notes
0/8000

Notes stay private to your browser until account sync is configured.

README
3 min read18 headings

3.5 Bitwise Operators

Table of Contents

  1. What Are Bitwise Operators
  2. Binary Number Basics
  3. Bitwise AND (&)
  4. Bitwise OR (|)
  5. Bitwise XOR (^)
  6. Bitwise NOT (~)
  7. Left Shift (<<)
  8. Right Shift (>>)
  9. Zero-fill Right Shift (>>>)
  10. Practical Applications

What Are Bitwise Operators

Bitwise operators work on the binary representations of numbers, manipulating individual bits. JavaScript converts numbers to 32-bit signed integers before performing bitwise operations.

Why Learn Bitwise Operators?

Use CaseApplication
Flags & PermissionsCompact storage of multiple boolean values
PerformanceFaster than multiplication/division by powers of 2
GraphicsColor manipulation (RGB values)
EncryptionXOR-based encoding
Low-levelEmbedded systems, protocols

All Bitwise Operators

OperatorNameDescription
&ANDSets bit to 1 if both bits are 1
|ORSets bit to 1 if at least one bit is 1
^XORSets bit to 1 if exactly one bit is 1
~NOTInverts all bits
<<Left shiftShifts bits left, fills with 0s
>>Right shiftShifts bits right, preserves sign
>>>Zero-fill right shiftShifts bits right, fills with 0s

Binary Number Basics

Understanding Binary

Decimal 13 in binary:

Position:    8    4    2    1
Binary:      1    1    0    1
             โ†“    โ†“    โ†“    โ†“
Value:       8 +  4 +  0 +  1 = 13

Common Conversions

DecimalBinaryHex
000000x0
100010x1
501010x5
1010100xA
1511110xF
255111111110xFF

JavaScript Binary Methods

// Decimal to binary string
(13).toString(2); // "1101"

// Binary string to decimal
parseInt('1101', 2); // 13

// Binary literals (ES6)
const binary = 0b1101; // 13

Bitwise AND (&)

Returns 1 only if both bits are 1.

Truth Table

ABA & B
000
010
100
111

Visual Example

    12 = 1100
  &  5 = 0101
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
     4 = 0100

Position by position:
1 & 0 = 0
1 & 1 = 1
0 & 0 = 0
0 & 1 = 0

Common Uses

// Check if number is even (last bit is 0)
const isEven = (n) => (n & 1) === 0;

// Masking - extract specific bits
const extractLow4Bits = (n) => n & 0b1111;

// Clear specific bits
const clearBit3 = (n) => n & ~(1 << 2); // Clear 3rd bit (index 2)

Bitwise OR (|)

Returns 1 if at least one bit is 1.

Truth Table

ABA | B
000
011
101
111

Visual Example

    12 = 1100
  |  5 = 0101
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    13 = 1101

Position by position:
1 | 0 = 1
1 | 1 = 1
0 | 0 = 0
0 | 1 = 1

Common Uses

// Set specific bits
const setBit3 = (n) => n | (1 << 2); // Set 3rd bit

// Combine flags
const READ = 0b001;
const WRITE = 0b010;
const EXECUTE = 0b100;
const permissions = READ | WRITE; // 0b011

// Floor positive numbers (faster than Math.floor)
const floor = (n) => n | 0; // 3.7 | 0 = 3

Bitwise XOR (^)

Returns 1 if bits are different.

Truth Table

ABA ^ B
000
011
101
110

Visual Example

    12 = 1100
  ^  5 = 0101
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
     9 = 1001

Position by position:
1 ^ 0 = 1
1 ^ 1 = 0
0 ^ 0 = 0
0 ^ 1 = 1

XOR Properties

// Self-inverse: a ^ a = 0
5 ^ 5; // 0

// Identity: a ^ 0 = a
5 ^ 0; // 5

// Commutativity: a ^ b = b ^ a
3 ^ 5; // Same as 5 ^ 3

// Associativity: (a ^ b) ^ c = a ^ (b ^ c)

Common Uses

// Toggle specific bits
const toggleBit = (n, pos) => n ^ (1 << pos);

// Swap without temp variable
let a = 5,
  b = 3;
a = a ^ b; // a = 6
b = a ^ b; // b = 5
a = a ^ b; // a = 3

// Simple encryption/decryption
const encrypt = (char, key) => char ^ key;
const decrypt = (encrypted, key) => encrypted ^ key;

Bitwise NOT (~)

Inverts all bits (0 becomes 1, 1 becomes 0).

How It Works

   ~5  = ~(00000000000000000000000000000101)
       =  (11111111111111111111111111111010)
       = -6 (in two's complement)

Formula: ~n = -(n + 1)

Examples

~5; // -6
~-3; // 2
~0; // -1
~-1; // 0

Common Uses

// Check if item exists in array (indexOf returns -1 if not found)
const arr = [1, 2, 3];
if (~arr.indexOf(2)) {
  // ~(-1) = 0 (falsy), ~(1) = -2 (truthy)
  console.log('Found!');
}

// Double NOT for integer truncation
~~3.7; // 3 (faster than Math.floor for positive)
~~-3.7; // -3 (different from Math.floor for negative!)

Left Shift (<<)

Shifts bits to the left, filling with 0s from the right.

Visual Example

5 << 2 = ?

   5 = 00000101
       โ†“โ†“โ†“โ†“โ†“โ†“
After shift left by 2:
  20 = 00010100

Lost bits โ† 00000101 โ† Added 0s

Mathematical Meaning

// Left shift by n = multiply by 2^n
5 << 1; // 10  (5 ร— 2)
5 << 2; // 20  (5 ร— 4)
5 << 3; // 40  (5 ร— 8)
1 << 4; // 16  (1 ร— 16 = 2^4)

Common Uses

// Fast multiplication by powers of 2
const multiply8 = (n) => n << 3;

// Create bit masks
const mask = 1 << 5; // 0b100000 = 32

// RGB to single color value
const rgb = (r, g, b) => (r << 16) | (g << 8) | b;

Right Shift (>>)

Shifts bits to the right, preserving the sign bit.

Visual Example (Positive)

20 >> 2 = ?

  20 = 00010100
       โ†“โ†“โ†“โ†“โ†“โ†“
After shift right by 2:
   5 = 00000101

Added 0s โ†’ 00000101 โ†’ Lost bits

Visual Example (Negative)

-20 >> 2 = ?

 -20 = 11111111111111111111111111101100
       โ†“โ†“โ†“โ†“โ†“โ†“
After shift right by 2 (preserving sign):
  -5 = 11111111111111111111111111111011

Sign bit preserved โ†’ Added 1s โ†’ Lost bits

Mathematical Meaning

// Right shift by n โ‰ˆ divide by 2^n (with floor)
20 >> 1; // 10  (20 รท 2)
20 >> 2; // 5   (20 รท 4)
-20 >> 2; // -5  (preserves sign)

Zero-fill Right Shift (>>>)

Shifts bits to the right, always filling with 0s (ignores sign).

Difference from >>

// Positive numbers: same result
20 >> 2; // 5
20 >>> 2; // 5

// Negative numbers: very different!
-20 >> 2; // -5 (sign preserved)
-20 >>> 2; // 1073741819 (treated as unsigned)

Common Uses

// Convert to unsigned 32-bit integer
const toUint32 = (n) => n >>> 0;

-1 >>> 0; // 4294967295 (max uint32)
-2 >>> 0; // 4294967294

Practical Applications

1. Permission Flags

// Define permission flags
const NONE = 0b0000; // 0
const READ = 0b0001; // 1
const WRITE = 0b0010; // 2
const EXECUTE = 0b0100; // 4
const DELETE = 0b1000; // 8

// Combine permissions
let userPerms = READ | WRITE; // 0b0011 = 3

// Check permission
const hasRead = (perms) => (perms & READ) !== 0;
const hasWrite = (perms) => (perms & WRITE) !== 0;

// Add permission
const addPerm = (perms, perm) => perms | perm;

// Remove permission
const removePerm = (perms, perm) => perms & ~perm;

// Toggle permission
const togglePerm = (perms, perm) => perms ^ perm;

2. Color Manipulation

// RGB to hex color
const rgbToHex = (r, g, b) => {
  return '#' + ((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1);
};

// Hex to RGB
const hexToRgb = (hex) => {
  const val = parseInt(hex.slice(1), 16);
  return {
    r: (val >> 16) & 0xff,
    g: (val >> 8) & 0xff,
    b: val & 0xff,
  };
};

3. Fast Integer Operations

// Check if power of 2
const isPowerOf2 = (n) => n > 0 && (n & (n - 1)) === 0;

// Swap without temp
let x = 10,
  y = 20;
x ^= y;
y ^= x;
x ^= y;
// Now x = 20, y = 10

// Round down to nearest power of 2
const floorPowerOf2 = (n) => {
  n |= n >> 1;
  n |= n >> 2;
  n |= n >> 4;
  n |= n >> 8;
  n |= n >> 16;
  return n - (n >> 1);
};

4. Bit Counting

// Count set bits (population count)
const countBits = (n) => {
  let count = 0;
  while (n) {
    count += n & 1;
    n >>>= 1;
  }
  return count;
};

// Or using Brian Kernighan's algorithm (faster)
const countBitsFast = (n) => {
  let count = 0;
  while (n) {
    n &= n - 1; // Clear lowest set bit
    count++;
  }
  return count;
};

Summary

OperatorNameExampleResultUse Case
&AND12 & 54Masking, check bits
|OR12 | 513Set bits, combine flags
^XOR12 ^ 59Toggle, swap, encrypt
~NOT~5-6Invert, indexOf check
<<Left shift5 << 220Multiply by 2^n
>>Right shift20 >> 25Divide by 2^n (signed)
>>>Zero-fill right-1 >>> 04294967295Unsigned conversion

Next Steps

After mastering bitwise operators, proceed to:

  1. 3.6 Ternary Operator - Conditional expressions
  2. Practice bit manipulation problems
  3. Implement permission systems using flags

Skill Check

Test this lesson

Answer 4 quick questions to lock in the lesson and feed your adaptive practice queue.

--
Score
0/4
Answered
Not attempted
Status
1

Which module does this lesson belong to?

2

Which section is covered in this lesson content?

3

Which term is most central to this lesson?

4

What is the best way to use this lesson for real learning?

Your answers save locally first, then sync when account storage is available.
Practice queue