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.
| property | value |
|---|---|
| range | |
| resolution (step) | |
| distinct values |
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 hold | magnitude | fits? |
|---|
float32 spaces its values proportionally — the gap between representable numbers grows with magnitude. Fixed point spaces them uniformly. So they cross.
| format | step 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.