◄ WORLD V · SONNY 5DART 003 · a helldive at the net

BRESENHAM’S LINE error ± step

A dart thrown into the dark abstract landed on the algorithm that draws a straight line on a pixel grid using nothing but integer add and compare — no floats, no division, no y = mx + b. We light the pixels live, credit who actually made it, and find a deep irony waiting for I-13: a language with only floats would run the anti-float algorithm in floats. Three prongs, one dart.

THE TECHNIQUE an integer error term decides the step

Walk the major axis one pixel at a time. Carry an integer error term D. Each step, subtract 2·dy; when D would cross zero, step the minor axis too and add 2·dx back. The float line y = mx + b is never computed — the sign of an integer is the decision. Drag either endpoint, or throw a dart. live demo

D = 2*dy - dx // integer, once for x in x0..x1: plot(x, y) if D > 0: y += sy; D -= 2*dx // step minor axis D += 2*dy // every column
Bresenham pixel (integer)
true float line y=mx+b
endpoint — drag me
The orange line is the ideal geometry. The cyan pixels are what a purely-integer machine lights — and they hug it exactly, having never touched a float.
(,)
(,)

HISTORY & CREDIT credit where it is due

This one is refreshingly uncontested. One name, one lab, one plotter. cited

1962 · Jack Elton Bresenham, in the computation lab at IBM’s San Jose development lab, drives a Calcomp plotter attached to an IBM 1401 through the 1407 typewriter console. By his own account the algorithm was “in production use by summer 1962.”
1963 · presented at the ACM National Convention in Denver.
1965 · published as “Algorithm for computer control of a digital plotter” in the IBM Systems Journal — the paper the world cites.

No disputed authorship, no predecessor to name plainly — unusually clean provenance for a piece of code this famous. The “Bresenham” family (midpoint circle, ellipse) came later and carries his name by extension, not because he wrote all of them. What’s genuinely open: the same integer-decision idea was arrived at independently for circles and by others for anti-aliased variants (Wu), so “Bresenham” is now a technique-family label as much as one 1962 procedure. open

RECOMMEND FOR I-13 the anti-float algorithm, run in floats

Here is the irony this dart exists for. Bresenham’s entire value is being integer-only — exact, fast, no rounding. But I-13’s Constant is f64 and nothing else: no integer type at all. So I-13 can run Bresenham — it needs only + − * and compare, which I-13 has — but every “integer” error term is secretly a float. The algorithm works, and in the same breath defeats its own reason to exist. Measured on the live compiler, not asserted:

i13 run prec.i13 => I b <- 9007199254740993 prints b = 9007199254740992 (2^53 + 1 is UNREPRESENTABLE in f64 — the literal silently rounds down) i13 run intdiv.i13 => 7 / 2 prints q = 3.5 (division is float; there is no integer 3) i13 check mod.i13 => mod.i13:3:10 E0001 unexpected character `%` (no remainder either)

For a small line every coordinate is well under 2^53, so f64 holds it exactly and I-13’s Bresenham lights the correct pixels — the demo above would render identically. The danger is invisible: cross 2^53 (a large canvas, a tiled address, an accumulated counter) and the error term stops being exact, and nothing warns you — the run just prints RUN OK.

Recommend — a diagnostic, not a new operator. Bresenham needs no >>, no %, no new BinOp: add / subtract / compare already suffice. What it needs is an integer-domain diagnostic — extend Verdict with one line: “every value stayed an exact integer below 2^53.” That is a new report row, zero new alphabet symbols, and it fits I-13’s existing habit of Verdict naming its own boundaries (COVERED / NOT COVERED). It turns the silent 2^53 cliff into a stamped, honest result.
Tradeoff (honest): a real integer type would give exactness for free but would break the counted “Constant is f64 only” identity and add machinery to the 13-symbol purity. The diagnostic is the cheaper, truer move: it doesn’t change what I-13 is, it just makes I-13 admit when a float has stopped behaving like an integer — the same gap the language panel flagged, answered in I-13’s own grain.