ZigZag Integer Encoder

Encode signed integers via protobuf ZigZag encoding

Ad placeholder (leaderboard)

ZigZag encoding is the trick Protocol Buffers uses to store signed integers efficiently. Negative numbers in two’s complement have all their high bits set, which would waste bytes in a varint. ZigZag remaps the signed range so that small magnitudes — whether positive or negative — become small unsigned values that pack into one or two bytes.

How it works

For an n-bit value the encoding interleaves negatives and non-negatives:

encoded = (value << 1) XOR (value >> (n - 1))

  0 ->  0
 -1 ->  1
  1 ->  2
 -2 ->  3
  2 ->  4

The left shift by one frees the lowest bit to carry the sign, while the arithmetic right shift by n - 1 smears the original sign bit across the whole word so the XOR flips the right bits. Decoding inverts it with (encoded >> 1) XOR -(encoded AND 1): the masked low bit reconstructs the sign and the right shift restores the magnitude.

Tips and notes

Select the width that matches your protobuf field: sint32 uses 32-bit ZigZag, sint64 uses 64-bit. The encoder enforces the signed range for the chosen width, and the decoder expects a non-negative encoded value. ZigZag is usually the first step before varint encoding — encode the signed number here, then feed the resulting unsigned value into the varint tool to get the final wire bytes.

Ad placeholder (rectangle)