Number Line Zoomer
An interactive number line that zooms around a chosen center, exposing the ULP (unit-in-the-last-place) grid for IEEE 754 floats. Each zoom step halves the visible range, surfacing the spacing between adjacent representable values at float32 or float64 precision. Sibling to FloatBitViewer — together they teach why 0.5 + 1e-9 rounds back to 0.5 in low-precision training and why subnormals exist near zero.
Number line zoomer · float32Number line zoomer: float32, center 0, range 0.007813, ULP 1.40e-45, 5.58e+42 representable values in window.
float32 · zoom 2^8center 0 range 0.007813 ulp 1.40e-45
2^8
Customize
Window
0.00
2^8
Display
float32
Installation
npx shadcn@latest add https://craftbits.dev/r/number-line-zoomer.jsonUsage
import { NumberLineZoomer } from "@craft-bits/core";
<NumberLineZoomer defaultCenter={0} defaultZoomLevel={8} precision="float32" />Drive center and zoom externally:
<NumberLineZoomer
center={center}
zoomLevel={zoom}
precision="float32"
onCenterChange={setCenter}
onZoomLevelChange={setZoom}
/>Hide the ULP ticks for a dense composition:
<NumberLineZoomer
defaultCenter={2 ** 20}
defaultZoomLevel={0}
precision="float32"
showUlps={false}
/>Anatomy
- Two state pairs, both Radix.
center/defaultCenterpluszoomLevel/defaultZoomLevel. Pass the controlled prop and anon*Changecallback, or thedefault*prop alone — the component picks the right mode automatically. - Each zoom level halves the range. Zoom 0 spans
[-1, 1]around the center; zoom 8 spans roughly[-0.004, 0.004]; zoom 20 spans roughly[-1e-6, 1e-6]. The center is the fixed point of the zoom — pan by movingcenter, not by changing the bounds. - Math.fround is the truth for float32. Every center is snapped to the nearest float32 (or left untouched for float64) before rendering, so the highlighted middle always sits on a representable value rather than between two ULPs.
- ULP grid via the IEEE 754 formula. For a normal float
xat precisionp, the ULP is two raised to the power of floor(log2(absolute x)) minus the mantissa bit count. Ticks anchor on the center and march outward by that ULP. Near zero (and in the subnormal range) the formula collapses to the smallest representable subnormal, so the grid stays well-defined even when the center is exactly zero. - Dense-band fallback. When the number of ticks in the window exceeds 200 — common for float64 at moderate zoom — drawing them individually would crush the renderer. Above that threshold the component swaps to a translucent band with 80 illustrative strokes and an exact count in the readout, so the visual still reads as "too dense to draw".
- SPRINGS.smooth for the visible window. The center cross-hair animates between zoom and center changes;
prefers-reduced-motion: reducecollapses both to an instant swap.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
center | number | — | Controlled center value. Pair with onCenterChange. |
defaultCenter | number | 0 | Uncontrolled initial center. |
onCenterChange | (center: number) => void | — | Fires whenever the center changes. |
zoomLevel | number | — | Controlled zoom level in 0 to 20. Each step halves the visible range. |
defaultZoomLevel | number | 0 | Uncontrolled initial zoom level. |
onZoomLevelChange | (zoomLevel: number) => void | — | Fires whenever the zoom level changes. |
precision | "float32" | "float64" | "float32" | Which IEEE 754 precision to sample representable values from. |
showUlps | boolean | true | Whether to render the ULP ticks. When false, only the axis line, center marker, and readout are drawn. |
transition | Transition | SPRINGS.smooth | Spring used for the center marker between zoom or center changes. |
className | string | — | Merged onto the root via cn(). |
Accessibility
- The figure is
role="figure"with a labelled title that names the precision and zoom level. - An
aria-live="polite"summary announces the precision, center, range, ULP, and approximate tick count whenever the window changes. - The zoom slider uses
LabeledSliderunderneath — rendering as a native range input with Arrow / Home / End keyboard support and a labelled value readout. - Color is never the only signal: the textual header above the chart spells out the center, range, and ULP in mono.
prefers-reduced-motion: reducesnaps the center marker and zoom transitions with no spring.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/nn/NumberLineZoomer.tsx). The source bundled a lesson-specific format picker (FP8 E4M3, FP8 E5M2, FP16), interval picker over fixed power-of-two intervals, phase-tracked narration, and the project'sChallengeBtnplusSvgLabelchrome. The library version is a pure number-line zoom primitive — controlled and uncontrolledcenterandzoomLevelpairs, IEEE 754 float32 / float64 sampling viaMath.froundand the ULP formula, aLabeledSliderfor zoom, a dense-band fallback for sub-threshold tick densities, andcb-accent/cb-border-strongsemantic tokens in place of the inline palette.