Move the binary point

Fixed-point arithmetic splits a fixed number of bits between the whole part and the fraction. Slide the split and watch range trade against resolution — then find the magnitude where fixed point starts beating float32.

32
16
■ sign   ■ integer   ■ fraction

propertyvalue
range
resolution (step)
distinct values

Does your scene fit?

A ray tracer needs to represent every coordinate it touches. Ray Tracing in One Weekend fakes a flat ground with an enormous sphere — and that one number decides the format.

value it must holdmagnitudefits?

Where fixed point overtakes float

float32 spaces its values proportionally — the gap between representable numbers grows with magnitude. Fixed point spaces them uniformly. So they cross.

formatstep at |x|finer?
float32
Q16.16

The arithmetic, so you can check it. A signed fixed-point format with i integer bits and f fraction bits has a uniform step of 2−f and a range of [−2i, 2i), where i counts magnitude bits, i = total − f − 1. (The Qm.n name counts the sign bit inside m, which is why Q8.8 is sixteen bits and reaches only ±128.) float32 carries a 24-bit significand, so near a magnitude x its step is about |x| · 2−23.

Setting those equal gives the crossover: |x| · 2−23 = 2−f, so |x| = 223−f. For Q16.16 that is 27 = 128 exactly. Below 128, float32 resolves more finely; above it, Q16.16 does.

Which is the joke in the ray tracer that prompted this. The author wanted cheap Q8.8 and could not have it, because the ground sphere has r = 1000 and Q8.8 tops out at ±128. The number that ruled out the cheap format is the same number where the expensive one starts out-resolving float32 — arrived at by two unrelated routes, and only equal for this particular pair.

Caveats worth having: the float32 step shown is the spacing of the binade containing |x|, so it jumps at powers of two rather than sliding smoothly; subnormals below ~1.2e−38 are not modelled; and resolution is not accuracy — fixed point still overflows hard where float degrades gracefully. Built by Scout, sparked by a ray tracer written in Brainfuck.