bitlvl
EN

Gray code, BCD & popcount

Enter a number in decimal, hex or binary. You get its Gray code (and the reverse), its BCD packing, the number of set bits and the parity, with the formulas used.

Width

Gray code sequence

Gray code

In ordinary binary, counting from 7 (0111) to 8 (1000) flips four bits at once. If those bits are read by a mechanical encoder or sampled by a clock while they change, any mix of old and new bits can appear, and a momentary 1111 (15) is a large error. Gray code (reflected binary code) orders the numbers so that consecutive values differ in exactly one bit. Rotary encoders, Karnaugh maps, some ADCs and error-correction schemes use it.

The conversion is one line each way:

gray   = n ^ (n >> 1)
binary = g; while (g >>= 1) binary ^= g;   // XOR with all right shifts

BCD

Binary-coded decimal stores each decimal digit in its own 4-bit nibble: 1234 becomes 0001 0010 0011 0100, which is 0x1234 as a hex number. It wastes some space (nibbles A–F are never used) but makes decimal display and exact decimal arithmetic trivial, which is why clocks, calculators, financial COBOL and the real-time clock chip in every PC use it. Reading a BCD byte as plain binary gives nonsense, which is the usual bug.

Popcount and parity

The Hamming weight (popcount) is the number of 1 bits. It is a single instruction on modern CPUs (POPCNT) and the basis of Hamming distance, bitset cardinality and some hashing tricks. Parity is popcount mod 2; a parity bit is the simplest error-detecting code, catching any single flipped bit.

// Kernighan's trick: each step clears the lowest set bit
int count = 0; while (n) { n &= n - 1; count++; }

Questions

Why do rotary encoders use Gray code?

Between two adjacent positions only one contact changes, so a reading taken mid-transition is always one of the two neighbouring values, never a wild one. Binary encoders can show any value during a multi-bit transition.

Is Gray code unique?

The reflected binary code is the standard one, but any ordering where neighbours differ in one bit is “a” Gray code. Balanced and n-ary Gray codes exist for special uses.

How do I convert BCD to binary in code?

Take each nibble as a digit: value = value*10 + nibble, from the most significant nibble down. Or, for two-digit bytes, ((b >> 4) * 10) + (b & 0x0F). Many RTC chips need exactly this.

What is the fastest way to count bits?

Use the built-in: __builtin_popcount (C), bits.OnesCount (Go), int.bit_count() (Python 3.10+), u32::count_ones (Rust). They compile to a single instruction where available.