Four Bits Per Digit, One Glow Per Tube
The K155ID1 chip that’s supposed to drive my Nixie tubes takes a 4-bit input and lights one of ten cathodes. Input 0000 lights the zero. Input 1001 lights the nine. Input 1010 through 1111? Undefined — the chip wasn’t designed for them.
This is Binary Coded Decimal: each decimal digit gets its own 4-bit nibble, wasting 6 of the 16 possible codes to preserve the human-readable boundary between 9 and 10. Calculators of the 1960s thought this way because their users did. The UNIVAC 1004, the IBM 1401, the NCR 315 — these machines processed decimal transactions for banks and insurance companies who didn’t want to explain why $100.00 became $99.9999999847 after a floating-point roundtrip.
(defn int->bcd [n]
(mapv #(Integer/parseInt (str %)) (str n)))
(defn bcd->int [digits]
(reduce (fn [acc d] (+ (* acc 10) d)) 0 digits))
;; 3038 → [3 0 3 8] → 3038
(bcd->int (int->bcd 3038)) ; => 3038
Clojure’s approach is almost too casual — treat the number as a string, split by character, parse each digit. No bit manipulation at all. This is the high-level lie about BCD: that it’s just digits. The truth lives at the hardware level, where those four bits per digit require actual wires.
Ada, born from defence contracts and serious about bit-level control, exposes the mechanics:
with Ada.Text_IO; use Ada.Text_IO;
procedure BCD_Convert is
type BCD_Digit is mod 16;
Altimeter : constant Integer := 3038;
Digit : BCD_Digit;
begin
for I in reverse 0 .. 3 loop
Digit := BCD_Digit((Altimeter / 10**I) mod 10);
Put(BCD_Digit'Image(Digit));
end loop;
end BCD_Convert;
Output: 3 0 3 8
The mod 10 is doing the work: extracting each decimal place, guaranteeing we never exceed 9. The remaining 6 bits of each nibble stay dark, unused, a tax we pay for human legibility.
My altimeter setting — 30.38 inches — will display as 3038 across four IN-12 tubes. Each tube receives a 4-bit code from a shift register. Each 4-bit code represents one decimal digit. The glow is decimal, even if the wires are binary.
BCD fell out of favour when memory became cheap and floating-point processors became fast. But financial systems still use it (the DECIMAL type in SQL, Java’s BigDecimal), and Nixie tube clocks still demand it. The K155ID1 hasn’t changed its interface since 1974. It still expects four bits, still refuses to count past nine, still glows orange when it gets what it wants.