Bitwise Operations Reference

AND, OR, XOR, NOT and shift operators with truth tables, a live calculator and masking patterns

Searchable bitwise operator reference with AND, OR, XOR, NOT and shift truth tables, a live 32-bit calculator showing binary and decimal results, and the classic set/clear/toggle/test bit-manipulation patterns. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is the difference between >> and >>>?

Both shift bits to the right, but >> is an arithmetic shift that preserves the sign bit (sign-extends), so -8 >> 1 stays negative. >>> is a logical shift that fills the left with zeros and treats the value as unsigned, so -1 >>> 0 yields 4294967295. Use >> for signed division by powers of two and >>> when you want the raw unsigned bit pattern.

Bitwise operators work directly on the binary representation of integers, one bit at a time. They are the foundation of flags, masks, hashing, compression and low-level protocol parsing. This reference lists every operator with its truth table, gives you a live calculator, and collects the masking patterns you reach for most.

How it works

Each binary operator combines the bits of two numbers position by position:

  • & (AND) yields 1 only when both bits are 1 — used to mask off bits.
  • | (OR) yields 1 when either bit is 1 — used to set bits.
  • ^ (XOR) yields 1 when the bits differ — used to toggle bits.
  • ~ (NOT) inverts every bit; in two’s complement ~x equals -(x + 1).

Shifts move the whole pattern: x << n multiplies by 2^n, x >> n divides by 2^n while preserving sign, and x >>> n divides treating the value as unsigned. The shift count is taken mod 32 on 32-bit operations.

Example

To pack a true/false flag into bit 3 of a byte and read it back:

let flags = 0;
flags |= (1 << 3);        // set bit 3 → 0b0000_1000 = 8
const isOn = (flags >> 3) & 1; // read bit 3 → 1
flags &= ~(1 << 3);       // clear bit 3 → 0

Notes

  • x & (x - 1) clears the lowest set bit; counting how many times you can do this gives the population count (number of set bits).
  • x & -x isolates the lowest set bit, handy for Fenwick/BIT structures.
  • A value is a power of two exactly when x > 0 && (x & (x - 1)) === 0.
  • In JavaScript bitwise operators coerce to signed 32-bit integers, so very large values lose precision — switch to BigInt for 64-bit work.

Practical bit-manipulation patterns

These four idioms cover the vast majority of real bitwise work:

// Set bit n in x
x = x | (1 << n);

// Clear bit n in x
x = x & ~(1 << n);

// Toggle bit n in x
x = x ^ (1 << n);

// Test whether bit n is set (returns 0 or 1)
const isSet = (x >> n) & 1;

Beyond those four, a handful of patterns appear constantly in lower-level code:

// Check if x is a power of two
const isPow2 = x > 0 && (x & (x - 1)) === 0;

// Clear the lowest set bit (Brian Kernighan's trick)
x = x & (x - 1);

// Isolate the lowest set bit
const lowestBit = x & -x;

// Count set bits (population count / popcount)
let count = 0;
let n = x;
while (n) { n &= n - 1; count++; }

Practical uses in everyday code

Feature flags. A single integer can store 32 boolean flags — set flag 5 with flags |= 1 << 5, clear it with flags &= ~(1 << 5), and check it with (flags >> 5) & 1. This pattern is common in game engines, permission systems, and state machines where storing 32 separate booleans in an object would be wasteful.

Fast division and modulo by powers of two. x >> 1 is the same as Math.floor(x / 2) for non-negative integers, and x & (n - 1) is the same as x % n when n is a power of two — both are faster than the division operator in performance-sensitive loops.

Networking and protocols. IP addresses, subnet masks, and packet headers are bit-fields. Masking with & extracts a subnet (ip & mask), and | assembles it back. The same technique applies to reading fields out of a binary file format or a WebSocket frame header.

Hash functions and pseudo-random generators. XOR and shift are the core operations in many fast hash functions (FNV, MurmurHash) and in LCG and xorshift random-number generators, because they mix bits cheaply without branching.