---
format: 1
concept: "logarithms"
kind: "figure"
title: "Halve it down to 1"
labels: {"lang":"en","level":"beginner","approach":"visual"}
changes: []
by: "si"
declaration: {"company":"anthropic","model":"claude-opus","version":"5.5","thinking":"high","app":"claude-code","tools":[],"sources":[]}
---
A slider sets a number $n$ from 1 to about a billion, in powers of 2 and in between. Below it, a bar for each halving: $n$, then half of it, then half again, rounded up, until 1. The count of halvings is $\log_2 n$ rounded up, shown beside the exact value. Moving from a thousand to a million adds only ten bars. Every number is shown as text; the bars are drawn with plain boxes whose widths are on a log scale, so even a billion fits.

```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
:root{--paper:#fbfbfd;--ink:#1d1f24;--muted:#6b6f78;--line:#dcdee3;--accent:#3d6fb6;--soft:#e6edf7;color-scheme:light dark}
@media (prefers-color-scheme:dark){:root{--paper:#16181c;--ink:#eceef2;--muted:#9aa0aa;--line:#33363d;--accent:#7aa5e8;--soft:#1f2a3b}}
body{margin:0;font:16px/1.5 system-ui,sans-serif;background:var(--paper);color:var(--ink);padding:16px;display:flex;flex-direction:column;gap:10px}
input[type=range]{width:100%;accent-color:var(--accent)}
.big{font-size:22px;font-weight:700;font-variant-numeric:tabular-nums}
ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:3px}
li{display:flex;align-items:center;gap:8px;font-variant-numeric:tabular-nums;font-size:14px}
li span.bar{height:12px;background:var(--accent);border-radius:3px;min-width:3px}
li span.n{min-width:7em;text-align:right;color:var(--muted)}
:focus-visible{outline:3px solid var(--accent);outline-offset:2px}
</style>
</head>
<body>
<label for="s">n = <span class="big" id="n"></span></label>
<input id="s" type="range" min="0" max="60" value="20" aria-describedby="out">
<p id="out" aria-live="polite"></p>
<ol id="bars" aria-label="Each halving"></ol>
<script>
const s = document.getElementById("s"), out = document.getElementById("out"), bars = document.getElementById("bars"), nEl = document.getElementById("n");
// Slider steps are half-powers of 2: 1, 1.41, 2, 2.83, 4, … up to 2^30, rounded to whole numbers.
const value = (k) => Math.max(1, Math.round(2 ** (k / 2)));
function draw() {
  const n = value(Number(s.value));
  nEl.textContent = n.toLocaleString();
  const steps = [];
  for (let x = n; ; x = Math.ceil(x / 2)) { steps.push(x); if (x <= 1) break; }
  const halvings = steps.length - 1;
  out.textContent = `${halvings} halving${halvings === 1 ? "" : "s"} to reach 1. log₂ ${n.toLocaleString()} ≈ ${Math.log2(n).toFixed(2)}.`;
  bars.textContent = "";
  const top = Math.log2(n) + 1;
  for (const x of steps) {
    const li = document.createElement("li");
    li.innerHTML = `<span class="n">${x.toLocaleString()}</span><span class="bar" style="width:${((Math.log2(x) + 1) / top) * 70}%"></span>`;
    bars.append(li);
  }
}
s.addEventListener("input", draw);
draw();
</script>
</body>
</html>
```

```json
{
  "libraries": [],
  "strings": {}
}
```
