Floating-Point Numbers Are Already Logarithms
IEEE 754 doubles store numbers as exponent plus mantissa, a decomposition that makes building math functions from scratch surprisingly tractable. · 6 min read
When implementing transcendental functions in a bare-metal assembly project, the IEEE 754 format turns out to be the most useful tool available. The exponent field is a coarse base-2 logarithm. The mantissa is the fractional refinement. Every 64-bit double is already stored as a decomposition that maps almost directly onto the algorithms for exp, ln, and power functions.
The Layout
A double splits into three fields: one sign bit, eleven exponent bits biased by 1023, and 52 mantissa bits encoding the fractional part of a normalised 1.something value. The number’s actual value is (-1)^sign × 2^(exponent - 1023) × 1.mantissa. That middle term is what makes things interesting. If you need ln(x), you already have the integer part of log₂(x) sitting in bits 52 through 62. Extract it with a shift and a mask, subtract 1023, and you have the coarse answer. The mantissa gives you the rest.
ln(x): Disassemble, Refine, Reassemble
- Extract the exponent: shift the raw bits right by 52, mask to 11 bits, subtract the bias. That gives you
e, the integer part of log₂(x). - Reconstruct the mantissa: zero out the exponent field and overwrite it with 1023 (the bias for 2⁰). You now have
m, a value between 1.0 and 2.0. - Refine with a polynomial: transform into
t = (m-1)/(m+1), which maps [1, 2) onto [0, ⅓). A five-term Padé series in t² gives roughly 14 digits of precision. - Combine:
ln(x) = e × ln(2) + 2 × t × P(t²).
The format did most of the heavy lifting. The polynomial is just a refinement pass on a decomposition that was already there.
exp(x): The Same Trick in Reverse
- Range reduction: compute
n = round(x / ln 2)andr = x − n × ln 2, so |r| ≤ ln(2)/2. Now e^x = 2^n × e^r. - Polynomial for e^r: a degree-6 Horner evaluation covers the reduced range with full double precision.
- Construct 2^n from bits: add 1023 to n, shift left by 52, load the result as a double. This writes the exponent field directly. In assembly it takes three instructions.
- Multiply: the product 2^n × P(r) is your answer.
Why It Generalises
The principle applies well beyond assembly. IEEE 754 is a logarithmic decomposition, and knowing that helps when reasoning about precision (the mantissa gives constant relative precision because it refines a logarithmic grid), when diagnosing instability (operations that cross exponent boundaries lose mantissa bits), and when understanding why “fast” approximations like the famous inverse square root hack work at all. They all exploit the same property: the exponent field is a coarse logarithm baked into every floating-point number.