Deep zoom: why it usually stops, and how it keeps going
Zoom into most fractal programs and somewhere around a span of the image goes wrong — first subtly gritty, then blocky, then a mosaic of solid squares. Nothing is wrong with the mathematics; the set has infinite detail. What ran out is the numbers.
The pixel-grid problem
A computer's standard number — the IEEE double — carries 53 binary digits of precision, about 15–16 decimal digits. Near , the gap between one representable double and the next is : numbers closer together than that are the same number to the machine. Now picture a view centred near with a span of : two neighbouring pixels differ only beyond the 16th digit, so they round to the identical double, iterate the identical orbit, and paint the identical colour. Whole blocks of pixels collapse onto one representable value each. That's the mosaic.

The precision ladder
Mandala watches the size of a pixel in complex units and switches arithmetic as you descend — automatically, per frame (the current tier shows in the HUD).
f64 — to about 10⁻¹³
Plain hardware doubles, on the GPU in a single shader pass or across a pool of WebAssembly workers. Fast, and fine for almost all sightseeing.
Double-double — to about 10⁻²⁷
Every number becomes an unevaluated pair of doubles whose exact sum carries roughly twice the digits (~31 significant decimals). Error-free transformations — tricks like two-sum, which recovers the exact rounding error of an addition into — keep the pair honest through every add and multiply. Several times slower than raw doubles, still entirely practical.
Perturbation — below 10⁻²⁷, and past 10⁻³⁰⁰
The clever one. Computing every pixel in hundreds-of-digits arithmetic would be ruinous. Instead, compute one orbit at the view's centre — the reference orbit — in arbitrary precision, as many digits as the depth demands. Every pixel is then expressed as a tiny difference from the reference: , where the pixel's is the reference's plus a tiny offset . Substitute into :
The reference terms cancel exactly, leaving the perturbation recurrence:
Everything in that equation is small — and are pixel-scale — so plain doubles handle it again until their exponent range is exhausted. One expensive orbit, a million cheap ones.
Rebasing: changing the ruler before it fails
Perturbation is accurate only while the pixel orbit remains a small correction to the reference. Near a minibrot the two can decorrelate: and become individually large while their sum is small, so the subtraction implicit in loses digits. That is the classic deep-zoom glitch.
Mandala detects the dangerous geometry — roughly, when the true value becomes smaller than the correction, — and rebases. It promotes the current true value to a fresh delta against the beginning of the same stored reference orbit, resets the reference index, and carries on. No second arbitrary-precision orbit is needed; only the ruler changes.
BLA: turning many iterations into one
Perturbation restores cheap arithmetic, but a pixel near the boundary may still need hundreds of thousands of iterations. Bivariate linear approximation (BLA) removes most of those steps.
Start from the exact quadratic delta recurrence:
While is sufficiently small, the quadratic term is negligible. One step is then an affine function of two independent small variables — the current orbit delta and the pixel's constant parameter delta :
That is why the name is bivariate: linear in the two perturbations and . Suppose one precomputed block applies and the next applies . Their composition is still the same kind of map:
So two steps collapse into one pair ; two such pairs collapse into four steps, then eight, sixteen, and so on. When a render worker receives a reference orbit, Mandala builds those power-of-two blocks into a binary table once for that orbit, not once per tile. At runtime a pixel asks for the longest aligned block that fits its remaining iteration budget.
The safety radius
Dropping cannot be allowed everywhere. Every table entry therefore stores a conservative radius : the approximation may run only while . At the single-step level Mandala uses a relative tolerance ; for the quadratic map the radius is based on . When two blocks are merged, the parent must be valid for both children. If block runs before block , its radius is restricted to
clamped at zero. Here bounds every pixel offset in the whole frame. This is the important contract: a smaller radius merely skips less; it never changes the answer. As a pixel approaches escape and outgrows the stored radius, lookup fails safely and the engine takes an exact perturbation step.
The cubic Multibrot uses the same table machinery with the level-zero derivative and a radius suited to the dropped quadratic and cubic terms. In a Julia view , so the half simply vanishes. Burning Ship, Tricorn and Celtic contain folds rather than a single complex- linear derivative, while Phoenix carries a two-value state; their exact perturbation recurrences do not fit this single- table and therefore do not use BLA.
WHAT BLA DOES — AND DOES NOT DO
BLA is a speed technique, not a source of precision. The arbitrary-precision reference and perturbation recurrence make the deep zoom correct; the BLA table proves when a run of those steps can be replaced by one conservative affine step. Mandala's BLA-vs-plain-perturbation tests pin that equivalence.
Past the exponent floor: floatexp
Perturbation has one more numerical floor. An IEEE double holds full precision only down to its smallest normal value, about ; below that a narrow band of subnormal doubles limps on with fewer and fewer significant bits, until past roughly the pixel offset is exactly zero — and an offset that has collapsed toward zero simply rides the reference orbit instead of carrying its own detail. More significant digits do not help when the exponent range has run out.
Mandala starts such pixels in an extended-range representation
with a double mantissa and a separate integer exponent . This floatexp value does not try to make every operation arbitrary precision; it only keeps extremely tiny deltas alive. The engine runs the family's exact delta recurrence in extended range until the value grows into normal-double territory, converts it to , and hands the rest to the fast perturbation loop. BLA begins after that handoff.
Every escape-time family has its own warm-up in both planes: the absolute-value families retain their sign-continuous identities, and Phoenix carries both its current and previous deltas. This is what lets all six escape-time families continue beyond rather than turning every initial offset into zero.

There is one more quiet ingredient: the coordinates themselves. At a span of the centre of your view needs hundreds of digits just to be written down, so Mandala carries view centres as arbitrary-precision decimals everywhere — including in share links and bookmarks. A link to a deep view reopens exactly there, to the last digit.
What this buys you
All six escape-time families ride this ladder and floatexp warm-up in both planes. Mandelbrot and the cubic Multibrot additionally use BLA; the non-analytic families take exact per-step perturbation paths. The two root-finding families cap at the double-double tier, around . For scale: at , a single pixel is to the full set roughly what a proton is to the observable universe — with about orders of magnitude to spare. The explorer's job is to make that depth boring to reach: scroll, and the ladder climbs under you.