roadmap
week 1 · day 1

Bits & the Idea of Meaning

The one idea the entire machine is built on

Easy 40 min 180 xp
After this you can
  • Explain why meaning in a computer is imposed, never intrinsic
  • Say why computers are binary — and why that's a physics decision, not a math one
  • Reconstruct any binary↔decimal conversion from the principle, without a lookup table
  • Read one byte three different ways and explain why all three are correct

Start with a question worth a year

Here is a question most people never ask, and almost everything else in this course is downstream of its answer: how can a machine — made of nothing but matter obeying physics — do something as abstract as arithmetic? A rock doesn't add. A river doesn't count. What did we do to a slab of sand (silicon *is* sand) to make it compute?

The answer is one idea, and if it lands properly today, the rest of the machine unfolds from it. So we are not going to rush to "0 and 1, here's how to convert binary." We are going to *earn* the idea, because it is the bedrock the CPU, assembly, C, and every exploit you will ever write are built on.

Meaning is not in the thing

Deep inside the machine is a switch — a tiny electronic component that is either conducting electricity or not. On, or off. That is *all* it physically is. It has no notion of "five"; it cannot; it is a switch.

Now the move that created computing. We *decide* — by pure human convention — to call the on-state 1 and the off-state 0. Nothing in physics says a conducting switch "is" a one. We impose that meaning on it. And once we have done it for one switch, we can do it for billions, and agree on rules for what patterns of them mean.

Sit with this, because it is the single most important sentence in the whole course:

Key idea
**A bit is a physical state. What it *means* is a rule we impose on it — the meaning is never in the bit itself.** The same on/off pattern can be the number 205, the number −51, the letter Í, one pixel's colour, or a fragment of a CPU instruction. The bits do not change between those readings; only the *interpretation* does. The machine never "knows" anything — it moves electrons according to physics, and *we* read meaning into where they land. To understand a computer is to always know which layer of interpretation you are looking at.

That single reframing is also why you can eventually take total control of a program. If meaning is imposed, then meaning can be subverted: convince a program to interpret *your data* as an *instruction*, and you own it. That is a buffer overflow, months from now — and it is exactly the idea you just learned, turned into a weapon. Hold the idea; the weapon comes later.

Why two states, and not ten?

Obvious follow-up: we count in tens, so why did we build machines that count in twos? It feels like a downgrade — one switch could have stored a whole decimal digit. The answer is not mathematical. It is physical, and it is about reliability.

Picture building a switch with ten distinct levels, so one component directly stores a digit 0–9. Now it must hold ten separate voltages precisely, and a reader must tell them apart — a billion times a second, across heat and electrical noise — without ever mistaking a 6 for a 7. That is an engineering nightmare. But a switch with two states — clearly on, clearly off, with a wide forbidden gap between them — is trivial to build reliably and trivial to read. Noise would have to be enormous to flip a definite *on* into a definite *off*.

Note
So computers are binary not because binary is special in mathematics, but because two states are the most physically trustworthy thing to build. This is your first taste of a pattern you will meet everywhere in this course: the machine is shaped by what physics makes *reliable* and *cheap*, not by what is mathematically elegant. Keep asking "why is it built this way?" — the answer is usually "because the physics made that the reliable choice."

Counting with two symbols — a principle, never a table

Now we can represent numbers. And I want to teach this so you never memorize a conversion table — you reconstruct any conversion from the one principle underneath, for the rest of your life.

The principle is positional notation, and you already own it — in base ten. When you write 205, each column is a power of ten:

205 in base ten — columns are powers of 10
   2        0        5
  10^2     10^1     10^0
  ×100     ×10      ×1
  200  +    0   +    5     =  205

Binary is the *exact same idea* with one change: because we have two symbols instead of ten, each column is a power of two instead of ten. That is the whole difference. Nothing else is new.

the same idea in base two — columns are powers of 2
  bit:    1     1     0     0     1     1     0     1
  power: 2^7   2^6   2^5   2^4   2^3   2^2   2^1   2^0
  value: 128    64    32    16     8     4     2     1
  on?:   128 +  64 +   0 +   0 +   8 +   4 +   0 +   1  =  205

The method, so you can derive it every time

To go decimal → binary you recall nothing — you *subtract the largest power of two that fits*, repeatedly, writing a 1 where it fit and 0 where it did not. Watch 205:

  • 128 fits (205 − 128 = 77) → bit 7 = 1
  • 64 fits (77 − 64 = 13) → bit 6 = 1
  • 32 too big → bit 5 = 0
  • 16 too big → bit 4 = 0
  • 8 fits (13 − 8 = 5) → bit 3 = 1
  • 4 fits (5 − 4 = 1) → bit 2 = 1
  • 2 too big → bit 1 = 0
  • 1 fits (1 − 1 = 0) → bit 0 = 1

Result: 11001101. To go the other way, add up the columns holding a 1. You just did arithmetic you can redo on *any* number, on paper, with no lookup. That gap — between deriving and recalling — is the whole difference between knowing and memorizing, and it is the standard for everything here.

The byte: why we clump bits into eights

A single bit answers one yes/no question — not much. So we group them, and the group the whole computing world settled on is eight bits: one byte. Eight switches, each on or off, give 2 × 2 × 2 × 2 × 2 × 2 × 2 × 2 = 2⁸ = 256 distinct patterns. Read as a plain unsigned number, one byte holds a value from 0 to 255.

Why eight? History and fit: eight bits is enough to give every letter, digit, and punctuation mark its own pattern (that is ASCII, soon), it is a tidy power of two, and it became the unit that memory is *addressed* in. The byte is the atom of memory — the machine points at byte number 0, byte number 1, and so on. It cannot point at a single bit; bits get manipulated only once a whole byte is pulled into the processor. File that away — it matters the instant we look at memory.

The payoff: one byte, three truths

Return to where we started, now that you can read bits. Take the eight switches 11001101. What is it?

  • As an unsigned number, it is 205 (you just derived that).
  • As a signed number, it is −51 (there is a scheme for negatives — that is the next lesson, and
  • it reuses these exact bits).
  • As a character, it is 'Í' in one common encoding.
  • As part of a machine instruction, it might be an opcode the CPU executes.

Every one of those is correct. The 8 switches are identical in all four cases. What differs is the rule we chose to read them with. This is not a trick or an edge case — it *is* how the machine works, at every level, all the time. The entire skill of understanding computers is knowing, at each moment, which interpretation is in force. You now hold the idea the whole machine is built on.

finished reading?
Your task, you write the code

Make the invisible visible

Everything you need is above — this is you proving the idea to yourself, by hand and in code, in bits.md. (1) Convert 200 and 89 to binary using the subtract-largest-power method, showing every step (no lookup table). (2) Convert 10110110 back to decimal by adding its columns. (3) Write a short C program that takes an unsigned char and prints its 8 bits high-to-low, then run it on 205 and confirm you see 11001101 with your own eyes — the abstraction made physical. (4) In two sentences, explain to an imaginary friend why the same byte can be both 205 and a letter, using the word 'interpretation'.

deliverable: bits.md (+ a small C program that prints a byte's bits)
build & run
$ gcc -Wall -o bits bits.c
$ ./bits # should print 11001101 for 205
self-review before running
  • You DERIVED every conversion by the method — no table used
  • Your program prints 11001101 for 205, matching the diagram
  • You can state, in your own words, why meaning is imposed and not intrinsic
  • You can give three correct readings of one byte and say what differs between them
stretchExtend the program to print, one per line, the 8 bits AND the decimal for 0, 1, 128, 255, and 205. Then answer WITHOUT looking it up: what is the largest number one byte can hold, and *derive* that from the number of bits rather than recalling it.

Self-check

01What does it mean that 'meaning is imposed' on a bit?
02Why are computers binary rather than decimal?
03You need binary 11010 in decimal. The right way to get it is to:
04The identical byte 11001101 can correctly be 205, −51, or the letter Í because:
0/4 correct · 0/4 checked