Docs

3.5-Bitwise-Operators

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
.5 Bitwise Operators - JavaScript Tutorial | DeepML