EMZETT.
Login

Bitmasks and bit operations

In short: With operators such as AND, OR, XOR and shift operations, individual bits of a number can be read, set and cleared in order to store many yes/no values in one number.

In more detail: An integer in the computer consists of bits (0 or 1). Bit operations work bit by bit and are very fast. A bitmask is a number that selects certain bits. Typical uses are file permissions, options (“flags”), network masks and hardware registers.

In Depth

The operators

OperatorNameEffect
&ANDbit is 1 if both are 1
|ORbit is 1 if at least one is 1
^XORbit is 1 if they differ
~NOTinvert all bits
<<left shiftshift left (times 2 per step)
>>right shiftshift right (divided by 2)

Setting, checking, clearing flags

const READ = 1;     // 0001
const WRITE = 2;    // 0010
const EXECUTE = 4;  // 0100
 
let perm = READ | WRITE;            // set     -> 0011
const canWrite = (perm & WRITE) !== 0; // check
perm = perm & ~WRITE;               // clear   -> 0001
perm = perm ^ EXECUTE;              // toggle  -> 0101

On Linux file permissions are built the same way: rwx corresponds to 4+2+1, hence chmod 755.

Useful tricks

  • Even or odd: n & 1.
  • Check for a power of 2: n > 0 && (n & (n - 1)) === 0.
  • Multiply by 2: n << 1, divide by 2: n >> 1.
  • Swap two variables with XOR (more of a curiosity).
  • Subnet masks: the address AND the mask gives the network address.

Pitfalls

In many languages numbers are limited to 32 bits for bit operations (in JavaScript they are converted to signed 32-bit integers). With negative numbers, arithmetic and logical right shift differ (>> and >>>). Do not confuse & with the logical &&. Clear names for flags and a comment save confusion.

See also: Binary, decimal, hexadecimal calculation, Logical operators, Operators