Fixed-Point Arithmetic

Do fractional math with integers — fast, deterministic and possible on chips without a floating-point unit.

Many microcontrollers (Cortex-M0/M3, AVR, most 8- and 16-bit parts) have no floating-point hardware: every float operation becomes a slow library call and pulls in kilobytes of code. Fixed-point arithmetic stores fractions as scaled integers instead.

Pitfalls

int16_t y = (a * b) >> 15; // a, b are Q15 int16_t int16_t y = (int16_t)(((int32_t)a * b + (1 << 14)) >> 15);

Make the wide intermediate explicit and round; relying on implicit promotion hides the intent and the result is truncated.

float v = raw * 3.3f / 4095; // on a Cortex-M0 uint32_t mv = (raw * 3300u + 2047u) / 4095u;

Without an FPU every float operation is a software routine — slower and much larger than integer math.

What decimal value does the Q15 number 16384 represent?

Why does Q16.16 multiplication need a 64-bit intermediate?

The product of two 32-bit values can need up to 64 bits (32 fractional bits before the shift back), so a 32-bit intermediate would overflow.