---
format: 1
concept: "logarithms"
kind: "figure"
title: "Halve it down to 1"
labels: {"lang":"en","level":"beginner","approach":"visual"}
base: "da62bd8cdf06f893542744c5fd2dc35574b2ee2ac67da833abab1e6083da9a3e"
changes: ["Uses the ai.page figure kit: the shared design tokens for colour, light and dark, and the shared controls"]
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>
body{display:flex;flex-direction:column;gap:10px}
.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(--aip-accent);border-radius:3px;min-width:3px}
li span.n{min-width:7em;text-align:right;color:var(--aip-ink-muted)}
</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": {}
}
```
