Shifeng Chen (陈诗峰) & Paul JL Wu agentic-portfolio 中文 Español 한국어 日本語✉️ Free list
← Back to portfolio

AI-NATIVE SERIES · NUMBERS AT FOUR AGES, EPISODE 4 OF 4 · AGE 20

Number vs Representation: The First Abstraction Every Programmer Uses (for Age 20)

By Shifeng Chen (陈诗峰) & Paul JL Wu · agentic-portfolio-lovat.vercel.app · 2026-10-15 · 14 min read

Cover: Number vs representation, the first abstraction every programmer uses, for age 20. Three cards: who it is for (20-year-olds who write code or will soon), what you leave with (a test for which layer a fact belongs to, and a round-trip converter), the one finding (positional notation is a log-length code with a fixed alphabet). Series strip with episode 4 highlighted.
Numbers at Four Ages, episode 4 of 4: age 20.

1-minute takeaway

What this is. An engineer's essay for 20-year-olds. The idea a child meets with apples and stones, that a number is not its name, is the same abstraction behind abstract data types, encodings, floating point and Unicode digits.

Why it matters. Bugs live in the gap between the value and the encoding: 0.1 + 0.2 that is not 0.3, a byte that is 251 or −5 depending on who reads it, a spreadsheet column that is base 26 with no zero. Knowing which layer a fact belongs to is a daily engineering decision.

What you can do after reading. Write a converter that round-trips every number through three encodings and passes the invariance test, find one bug in your own code that depends on representation, then teach the place-value proof to a 15-year-old.

Numbers at Four Ages — the series spine

▶ See it running: open the live demo public · no sign-in

  1. Age 7 · What is a number? episode 1
  2. Age 11 · Why so many ways to write numbers? episode 2
  3. Age 15 · Ten symbols, every number episode 3
  4. Age 20 · Number vs representation this episode

The one question: Why does every programmer need the difference between a number and its representation?

This episode does NOT teach the place-value proof itself; that is episode 3 (age 15). Continuous quantities (measuring rather than counting) are the next season.

What this episode is about: number vs representation

This is an engineer's essay about number vs representation: the difference between a value and the way it is written down or stored. It is for readers of about twenty who write code, or soon will. You need a laptop with Python and fifteen minutes for the exercise.

It is episode 4 of four, and it closes a loop.

This episode shows that the child's idea is the first abstraction every programmer uses. The ideas follow a chapter by 陈诗峰 (Shifeng Chen), co-author of this series, on numbers and their representations. Pushed one step further, they become a test you can run on your own code.

The series runs on one picture from the kitchen, climbing a ladder: eggs in a bowl, a restaurant, a fast-food stockroom. Here we reach the top rung, a national food supply chain. One crate of 42 cartons moves through a dozen systems. A barcode encodes it in one way, the warehouse database stores it as a binary integer, a CSV export writes the string "0042", and a spreadsheet keeps it in column AP. The quantity never changes; every system writes it differently. Supply-chain bugs live exactly in that gap.

Before you read on. You will end by walking a 15-year-old through the uniqueness proof from episode 3. Read as someone who will have to explain it. Across 39 studies, teaching after studying with that expectation scored g = 0.48, and teaching without it scored g = −0.02 (Kobayashi (2024), Educational Psychology Review (ERIC EJ1414484)).

Activity 1 · Count to 31 on one hand (invent first)

Your hand holds 0 to 5 if each raised finger means one. Without reading ahead, invent a way to count to 31 on that one hand, so that every number from 0 to 31 has its own finger pattern and you never reuse one.

Then use your system to show 19 and 31. Write down the rule you invented.

If each finger means double the one before it (1, 2, 4, 8, 16), you invented binary. 19 is 16 + 2 + 1, and 31 is all five fingers. Same hand, same number of fingers, six times the range. You changed the representation, and the numbers did not change at all. That is the whole essay in one gesture.

"Same number" is defined by pairing; a representation is an encoding

Episode 1's apple game is not a children's simplification. It is the definition of "same number" that Frege built arithmetic on. In the foundations of mathematics, two collections have the same number exactly when there is a one-to-one correspondence between them. This is Hume's Principle, at the root of Frege's 1884 construction of arithmetic (Zalta, Stanford Encyclopedia of Philosophy, "Frege's Theorem and Foundations for Arithmetic"). Nothing in that definition mentions digits.

A representation is an encoding of that value: a finite string over some alphabet plus a rule for reading it. Base ten, binary, Roman numerals, tally marks and the bits in a register are all representations. Software engineering names the same separation: an abstract data type is what a value does, separate from how it is stored, and the idea was set out in 1974 (Liskov & Zilles (1974), "Programming with abstract data types", ACM SIGPLAN Notices). A number is the original abstract data type, and every numeral system is one implementation of it.

A property that stays true under every encoding is an invariant of the value. Sorting invariants from encoding facts is the skill this essay trains. You can try it now in the Number Playground, a free page that writes any number nine ways and runs Chen's sorting game.

The core idea of the series, in one line: a number is the value, a representation is an encoding, and correct code depends only on the value.

Why positional notation won: a log-length code with a fixed alphabet

Chen's chapter is a history of compression, and an engineer can state it exactly.

Chen's sentence: place value turns the infinity of symbols into an infinity of places.

A log-scale bar chart of how many symbols it takes to write one million: tally marks 1,000,000; groups of five 200,000; Egyptian 1; base ten 7; base two 20; zero-free base ten 6. The base ten bar is orange. A note says Egyptian writes a million with one sign but has no sign above it.
Symbols needed to write one million. Positional notation turns a linear length into a logarithmic one.

That trade has a cost. Every place must be kept, including an empty one, which is what the placeholder zero is for. Zero is not strictly needed, though. In bijective (zero-free) base k the digits run from 1 to k. Every positive integer still has exactly one string, and the empty string is zero. You use one every day: spreadsheet columns A to Z, then AA, AB…, are bijective base 26. Excel allows 16,384 columns, and the last one is XFD (Microsoft, "Excel specifications and limits"): 24 × 26² + 6 × 26 + 4 = 16,384.

Activity 2 · Write the converter, then test what it must not change

Write three encoders and their decoders before reading the version below: base b with a zero digit, zero-free base ten (digits 1 to 9 and κ for ten, Chen's symbol), and spreadsheet column labels. Then write property tests. They should check that every encoding round-trips, and they should catch any "fact" that only holds for one representation.

One version, which passes every assertion when run:

DIGITS = "0123456789abcdefghijklmnopqrstuvwxyz"
def to_base(n, b):
    if n == 0:
        return "0"
    out = ""
    while n:
        n, r = divmod(n, b)
        out = DIGITS[r] + out
    return out
def from_base(s, b):
    return int(s, b)
def to_zero_free_ten(n):            # digits 1-9 and κ (ten); no 0
    out = ""
    while n:
        r = n % 10 or 10
        out = "123456789κ"[r - 1] + out
        n = (n - r) // 10
    return out
def from_zero_free_ten(s):
    n = 0
    for ch in s:
        n = n * 10 + "123456789κ".index(ch) + 1
    return n
def column_label(n):                # spreadsheet columns: zero-free base 26
    out = ""
    while n:
        r = n % 26 or 26
        out = chr(64 + r) + out
        n = (n - r) // 26
    return out
def column_number(s):
    n = 0
    for ch in s:
        n = n * 26 + ord(ch) - 64
    return n
assert to_zero_free_ten(3020) == "2κ1κ" and to_zero_free_ten(10**6) == "99999κ"
assert column_label(27) == "AA" and column_label(16384) == "XFD"
for n in range(1, 10_000):          # every encoding round-trips: the value is untouched
    assert from_base(to_base(n, 3), 3) == n
    assert from_zero_free_ten(to_zero_free_ten(n)) == n
    assert column_number(column_label(n)) == n
    assert (n % 3 == 0) == to_base(n, 3).endswith("0")              # true in base 3 ...
assert any((n % 3 == 0) != str(n).endswith("0") for n in range(1, 100))  # ... false in base ten: a fact about notation

Look at the last two assertions. "Divisible by 3 means the last digit is 0" holds for every number in base 3, and the final line shows it failing in base ten (3 is divisible by 3 and ends in 3). A property that holds in one encoding and fails in another belongs to the encoding, not to the number. Chen's sorting experiment, in which children decide whether a sentence is about the number or about its writing, is the same move as a property test that holds the value fixed and swaps the encoding. In base b the digit-sum shortcut works exactly for the divisors of b − 1 (Weisstein, MathWorld, "Divisibility Tests"), so the familiar rule for 3 and 9 is a fact about ten, not about three.

The same bits, different numbers: where it bites in code

Three runs you can reproduce in a Python prompt. Each is a representation fact leaking into the value layer.

The supply-chain version: a product code "0042" loaded into a spreadsheet becomes the number 42, and the leading zeros that were part of the identifier are gone. Somewhere a warehouse now believes that product 0042 (rubber ducks) and product 42 (also rubber ducks, different supplier) are the same thing, and orders twice the ducks. The code was an identifier stored as a string of digits, never a quantity. Knowing which layer a value lives in would have prevented it.

A map with a prediction: does a number have a body?

The series uses a lens from Paul's "play-engineering" notes, tested rather than assumed: a body has a spirit, bones, flesh and skin. In a number system:

A table titled The same map in code. Rows: spirit is the value forty-two, with the open question of whether it exists without code; bone is the type structure, one value in many types; flesh is parse, format and add with carry, which must be rewritten when the encoding changes; skin is the strings 42, 0042, 0x2A, 101010 and the spreadsheet column AP, new skin same value; two forms are int for counting and float for measuring, where 0.1 has no exact binary skin.
The same map in code. Whatever survives a change of encoding is the value; parse, format and carry are rewritten per encoding.

The prediction that makes it worth carrying: whatever survives a change of encoding belongs to the value; whatever breaks belongs to an implementation layer. Addition is spirit; the carry rule is flesh: one rule with N in it ("when you reach N, carry one"), so changing the base changes only the N, while addition itself never changes. In code that is the rule "test properties at the value layer, and keep encoding-specific facts behind the encoding's interface".

Where the map breaks:

  1. You can swap the bones (change base) and keep the spirit, which no body allows.
  2. "Discrete vs continuous" is an axis, not a layer. Aristotle drew it: "Quantity is either discrete or continuous." (Aristotle, Categories, Part 6, tr. E. M. Edghill (MIT Internet Classics Archive)). Everything here is discrete; measuring, and with it floats done properly, is the next season.
  3. Whether the spirit exists independently is open. On the Platonist view, numbers exist, are abstract and do not depend on any mind (Linnebo, Stanford Encyclopedia of Philosophy, "Platonism in the Philosophy of Mathematics"). On the nominalist view, there are no abstract number objects at all (Bueno, Stanford Encyclopedia of Philosophy, "Nominalism in the Philosophy of Mathematics"). Engineers can stay agnostic: the interface is what matters. That is itself a philosophical position, a functional one.

Why one idea fits four ages

This series bets on a claim usually traced to Jerome Bruner's The Process of Education (1960): that any subject can be taught in some intellectually honest form at any stage of development. We paraphrase it on purpose. We could not check the primary wording, so we do not quote it.

The test of "honest" is the same invariance test. Every episode states the same kernel, and nothing a 7-year-old learns here has to be unlearned at twenty. The pairing game is Hume's Principle. "5 is only a name" is the value/encoding split. The two-hand counter is the carry rule.

The playbook behind the series is built on studies you can check:

One more lens, labelled as mine. I hold that Truth, Love and Beauty are not three separate ideals but three faces of one Reality, and in my faith, of one Person. In this series they are also an engineering checklist that stands without the faith. A lesson needs to be true (checkable by the learner), loving (written for a particular person and met at their mistakes), and beautiful (one moment worth showing someone).

Mistakes that are half right

Now teach it

Your teach-back. Find a 15-year-old and work through "The proof: every number has exactly one spelling" in episode 3 with them. Don't write the steps for them: ask what the remainder is when 352 is divided by 3, then what happens to the quotient, and let them see that nobody chose the digits.

Outcome: the 15-year-old writes the remainder steps for 352 in base 3 unaided (111001) and says in one sentence why the last digit is forced. Post their age and result as a comment on this article.

Why it matters: five whys

The problem: a data pipeline drops the leading zeros from product codes, so 0042 and 42 merge and two products become one.

  1. Why did the codes merge? A loader parsed "0042" as the number 42. Both strings map to one value, so the identifiers collided.
  2. Why was it parsed as a number? The type was inferred from the look of the characters, digits only, rather than from what the field means.
  3. Why infer from the look? Because the system treated the representation (a string of digits) as if it were the value, the exact confusion Chen's chapter teaches children to avoid.
  4. Why wasn't it caught? No test held the value fixed while changing the encoding. A test that held the value fixed and changed the encoding would fail at once, the way the base-ten contrast line in the converter shows a base-3 "fact" failing in base ten.
  5. Root cause: code depended on the representation layer, not the value layer. The fix is the episode's rule: decide what the value is (quantity or identifier), keep encoding facts behind an interface (Liskov & Zilles (1974), "Programming with abstract data types", ACM SIGPLAN Notices), and test invariance across encodings.

Operate: run it this week

  1. Read the teach-ahead line.
  2. Count to 31 on one hand (2 minutes).
  3. Write the three converters and the property tests, then compare with the version above (15 minutes).
  4. Open the Number Playground. Type 16384 and 1000000, check your converter against its rows (including the spreadsheet-column row: 16384 is XFD), then play the N-or-R game.
  5. Find one place in your own code where a fact depends on representation (string vs number, float equality, a digit-only parser). Add one invariance test.
  6. Teach episode 3's proof to a 15-year-old.

Feedback: how you know it worked

Re-check yourself after a week. Testing beat rereading at 1 week (Roediger & Karpicke (2006), "Test-Enhanced Learning", Psychological Science 17). What this cannot see: whether the habit holds under deadline pressure. The property test in CI is the part that can.

Feedforward: tripwires, decided now

Truth, love and beauty in this episode

The 5S self-score

SClaimEvidence
SimpleThe prose reads at a grade-13 level or easier.Flesch–Kincaid grade of the prose: 8.4 (band ≤ 13), recomputed by node scripts/check-numbers-four-ages.mjs
SolidThe definitions and numbers are sourced; the code runs.Excel's 16,384 columns (Microsoft); Hume's Principle
SharpPositional notation is a log-length code with a fixed alphabet; correct code depends only on the value.Log-length · the property test
SMARTThis week: converter + one invariance test in your own code + one teach-back.Operate · Playground
SurpriseYour spreadsheet has counted in zero-free base 26 all along.XFD = 16,384
Truth · Love · BeautyRunnable claims; a person to teach; one idea at every age.Truth, love and beauty

Sources

  1. 陈诗峰 (Shifeng Chen), draft chapter 《第一章 数和数的表示形式》 ("Numbers and Their Representations"), 2026. Read the original chapter (PDF, Chinese). Co-author of this series.
  2. Zalta, E. N. "Frege's Theorem and Foundations for Arithmetic." Stanford Encyclopedia of Philosophy. plato.stanford.edu
  3. Liskov, B. & Zilles, S. (1974). Programming with abstract data types. ACM SIGPLAN Notices. Crossref 10.1145/942572.807045
  4. Weisstein, E. W. "Digit." MathWorld. mathworld.wolfram.com
  5. Weisstein, E. W. "Divisibility Tests." MathWorld. mathworld.wolfram.com
  6. Microsoft. "Excel specifications and limits." support.microsoft.com
  7. Unicode Character Database, UnicodeData.txt. unicode.org
  8. Aristotle. Categories, Part 6, tr. E. M. Edghill. classics.mit.edu
  9. Linnebo, Ø. "Platonism in the Philosophy of Mathematics." Stanford Encyclopedia of Philosophy. plato.stanford.edu
  10. Bueno, O. "Nominalism in the Philosophy of Mathematics." Stanford Encyclopedia of Philosophy. plato.stanford.edu
  11. Cowan, N. (2001). The magical number 4 in short-term memory. Behavioral and Brain Sciences 24. doi:10.1017/S0140525X01003922
  12. Kalyuga, S., Ayres, P., Chandler, P. & Sweller, J. (2003). The expertise reversal effect. Educational Psychologist 38. doi:10.1207/S15326985EP3801_4
  13. Kobayashi, K. (2024). Interactive learning effects of preparing to teach and teaching. Educational Psychology Review. ERIC EJ1414484
  14. Roediger, H. L. & Karpicke, J. D. (2006). Test-enhanced learning. Psychological Science 17. doi:10.1111/j.1467-9280.2006.01693.x
  15. DeLamater, M. (1999), on Bruner's hypothesis. Education Week. edweek.org (secondary; the primary wording was not checked)

Related

Written by Shifeng Chen (陈诗峰) & Paul JL Wu · agentic-portfolio · 2026-10-15. Co-written with 陈诗峰 (Shifeng Chen), from his chapter "Numbers and Their Representations" (the original PDF is linked in the first section and the sources). Built with playbook-math: one idea, four ages, every number from a checked source. Views are my own, not my employer's.