11 lessons

Digital Foundations

How arithmetic emerges from logic: binary and two's complement, why floating point approximates, gates, adders, and the step from combinational logic to stored state.

SourceCompilerInstructionsFront EndExecutionRegistersCachesMemoryI/OBehavior
What Actually Happens When You Add Two Numbers
▶ lab

One line of source becomes a handful of instructions, and the addition itself is the cheapest thing in it. The expensive question — the one this entire domain exists to answer — is where `a` and `b` were when the CPU went looking for them.

Q · When I write `int x = a + b;`, what does the machine actually do — and where does the time actually go?
Binary, and Why Everything Is Eventually Bits
▶ lab

Binary is not a numbering curiosity you convert for exam questions. It is the substrate: instructions, addresses, permission flags, protocol headers and floating-point values are all bit patterns, and hexadecimal exists because humans cannot read them otherwise.

Q · Why does everything in computing eventually come down to binary, and what does that actually change about how I read a value?
Bits, Bytes and Words — and Why "Word" Is Not a Fixed Size

The byte is nearly universal. The word is not: it means whatever a given architecture, compiler or document says it means, and the confusion this causes is responsible for a surprising share of portability bugs.

Q · What is a "word", why does its size keep changing depending on who is talking, and what actually depends on it?
Two's Complement: One Circuit for Addition and Subtraction

Negative numbers are not stored with a minus sign. They are stored so that ordinary binary addition produces the right answer without the hardware ever knowing a value was negative — which is why subtraction needs no separate circuit.

Q · How does hardware represent negative numbers, and why does that particular representation make the arithmetic circuitry simpler?
Integer Overflow: The Hardware Wraps, the Language Decides

Add one to the largest 8-bit signed value and the bits roll around to the most negative one. The hardware behaviour is simple and identical everywhere; what your language claims about it ranges from "wraps" to "this can never happen, and I will optimise on that basis".

Q · What happens when an integer exceeds the range its bits can represent — and why do different languages disagree about it so sharply?
Floating Point: Trading Precision for Range
▶ lab

A float is scientific notation in binary: a sign, an exponent that slides the point, and a fraction. That design buys an enormous range from a fixed number of bits, and it pays for it with precision that varies depending on how large the value is.

Q · How does a fixed number of bits represent both very large and very small numbers, and what does that design cost?
Why 0.1 + 0.2 Is Not 0.2 + 0.1's Problem

The famous result is not a bug and not a rounding display quirk. 0.1 has no exact binary representation for the same reason 1/3 has no exact decimal one, and every consequence — failed equality tests, drifting sums, order-dependent results — follows from that single fact.

Q · Why does `0.1 + 0.2` not equal `0.3`, and what should I actually do about it?
Boolean Logic: The Four Operations Hardware Actually Has

AND, OR, NOT and XOR are not programming conveniences layered over arithmetic. They are the primitive operations from which arithmetic itself is constructed, and they remain the cheapest instructions a CPU offers.

Q · Which logical operations does hardware actually implement, and why do the same four keep appearing everywhere above it?
Logic Gates: Where Software Stops and Physics Starts
▶ lab

A gate is a few transistors that compute one Boolean function of its inputs. Everything above — arithmetic, memory, control, the entire machine — is gates composed with other gates, and the two properties that matter are that composition is universal and that propagation takes time.

Q · What is physically doing the computing, and what constrains how fast it can go?
Building an Adder: Where Arithmetic Comes From

XOR gives you the sum bit, AND gives you the carry, and that is a half adder. Chain them and you can add any width — but the carry has to travel through every stage in turn, and that dependency is the reason adder design is a real engineering problem.

Q · How does arithmetic emerge from logic gates, and what limits how fast an addition can be?
Adding Memory: Combinational, Sequential and the Clock

Combinational logic has no memory — the output is a function of the inputs right now. Add feedback and you can store a bit; add a clock and you can control when stored values change. That step is what turns a calculator into a machine that executes programs.

Q · How does hardware remember anything, given that gates just compute a function of their current inputs?