FirmGod

Fixed-Point Q Format Converter

Convert between real values and fixed-point Q formats, see the stored value and the quantisation error, and settle which Q convention a datasheet means.

Presets:

0 to 15

Decimal, exponent notation accepted.

The integer actually stored in the register.

What gets stored

Exact stored value
0.100006103515625

You asked for 0.1. The difference is 6.100e-6, because the value is not a multiple of the format's step.

Raw integer3277
Raw hex0x0CCD
Raw binary0000110011001101
C literal3277

Format

The same format is written three ways in the wild. The bit breakdown below is the part that is never ambiguous.

Short formQ15Names the fractional bits only
Integer bits excluding signQ0.15Texas Instruments convention
Integer bits including signQ1.15Also widely used; same format
Bit layout1 sign + 0 integer + 15 fraction = 16
Range-1 to 0.999969482421875
Step (one LSB)0.000030517578125
Scale factor2^15

Multiplying in this format

Multiplication adds the fractional bits of both operands, so the raw product is in a different format from its inputs and has to be brought back down.

Product format15 + 15 = 30 fractional bits
Product width32 bits before the shift
Shift back>> 15
int32_t product = (int32_t)a * b;   /* 30 fractional bits */
int16_t result = (int16_t)(product >> 15);  /* back to Q15 */

The cast to 32 bits must happen before the multiply, not after. Multiplying two 16-bit values and assigning the result to a 32-bit variable overflows first and widens a number that is already wrong.

Fixed point is an integer with an agreed point

A fixed-point number is stored as an ordinary integer. The only extra thing is a convention: that the integer represents the real value multiplied by 2n, where n is the number of fractional bits.

stored = round(real × 2n) and real = stored / 2n

The hardware never learns about the point. The compiler does not track it. It exists only in your naming and your arithmetic, which is why fixed-point bugs are usually bookkeeping errors rather than numerical ones.

The naming is genuinely ambiguous

There is no single convention, and the disagreement is not academic — it changes the scale factor by two.

Written asMeansSeen in
Q15Fifteen fractional bits; the rest is impliedCMSIS-DSP, most informal use
Q0.15Zero integer bits plus a sign bit, fifteen fractionalTexas Instruments documentation
Q1.15The same format, with the sign bit counted in the 1Much application-note writing

All three describe one 16-bit word holding values in [−1, 1). The unambiguous statement is the bit breakdown: one sign bit, zero integer bits, fifteen fractional bits. The tool above prints all three labels next to that breakdown so a datasheet can be matched against it without guessing.

The asymmetry that bites

Two's complement holds one more negative value than positive. In Q15 that means the range is exactly −1 to +0.999969482421875 — the negative end reaches unity and the positive end does not.

This is why a normalised filter coefficient of 1.0 cannot be stored in Q15, and why DSP code either scales coefficients down by a factor of two or accepts saturation at 0x7FFF. It also means negating the most negative value overflows: −(−1) is not representable, and a saturating negate returns 0.999969 instead.

Multiplication changes the format

Adding two values in the same format keeps the format. Multiplying does not: the fractional bits add together, so multiplying two Q15 values produces a Q30 result that needs 32 bits.

Bringing it back means shifting right by the number of fractional bits you added. The order matters more than it looks:

int32_t product = (int32_t)a * b; widens first, then multiplies — correct.
int32_t product = a * b; multiplies two 16-bit values in 16-bit arithmetic on some targets, then widens a result that has already wrapped.

The same reasoning drives the accumulator width in a filter. Summing many products needs headroom above the product format, which is why DSP cores provide 40-bit accumulators for 16-bit data rather than 32.

Choosing a format

Work from the range, not from the precision you would like. Count the integer bits the largest possible magnitude needs — including intermediate results, not just inputs and outputs — and give everything left to the fraction.

  • Q15 and Q31 for signals normalised to [−1, 1), which is what audio and filter coefficients usually are.
  • Q16.16 when a value spans thousands but needs sub-unit precision — coordinates, timings, accumulated positions.
  • Q8.8 for sensor readings in engineering units. A temperature in Q8.8 covers −128 to +128 degrees in steps of about 0.004, which is finer than any sensor that reports it.

Over-reserving integer bits is not free: every unused integer bit halves the resolution. Under-reserving costs correctness the first time a transient exceeds the range you assumed.

Where the exact value matters

Because the scale is a power of two, every fixed-point value has a finite exact decimal expansion — unlike floating point, where the printed value is usually a rounded stand-in. The tool shows that exact expansion and the difference from what you asked for.

That difference is worth looking at when coefficients come from a design tool. A filter designed in double precision and quantised to Q15 is not the filter you designed, and for a sharp response the change can be large enough to move the cutoff or cost stability. Checking the quantised coefficients against the intended ones is cheaper than debugging the response later.

For the floating-point side of the same question, the IEEE 754 convertershows what a float actually stores, and the hex converter handles the raw integers once they are on the wire.

Frequently asked questions

Is Q1.15 the same as Q15?

Almost always yes, and that is the problem. Q15 names the fifteen fractional bits alone. Q1.15 names one integer position and fifteen fractional bits — but sources disagree about whether that 1 is the sign bit or an integer bit above it. Texas Instruments writes the same 16-bit format as Q0.15, counting the sign separately. Read the bit breakdown, not the label.

Why can Q15 not hold 1.0?

Because two’s complement is asymmetric. A 16-bit signed word runs from −32768 to 32767, and dividing by 32768 gives a range of −1 to 0.99997. The negative limit is exactly −1 but the positive limit falls one step short, which is why DSP code so often saturates at 0x7FFF rather than reaching unity.

What happens when I multiply two Q15 values?

The fractional bits add, so the raw product is Q30 and needs 32 bits to hold. Shifting right by 15 returns it to Q15. The cast to the wider type has to happen before the multiply — casting the result afterwards widens a number that has already overflowed.

Why use fixed point when the part has an FPU?

Often you should not. Fixed point earns its keep on parts without an FPU, where a float operation is a library call costing tens of cycles, and in code where the exact bit pattern matters — filter coefficients that must match a reference implementation, or values crossing a protocol boundary. On a Cortex-M4F doing ordinary control maths, float is usually simpler and fast enough.

How do I choose the number of fractional bits?

Work from the range first. Count the integer bits needed for the largest magnitude the value can reach, including intermediate results, then give every remaining bit to the fraction. Reserving one integer bit more than you need costs half your resolution, and reserving one too few costs correctness the first time a transient overshoots.

Does saturation or wraparound happen on overflow?

It depends on the instruction, not the format. Plain C integer arithmetic wraps, turning a large positive into a large negative — which in a control loop means full forward becomes full reverse. DSP extensions such as the ARM QADD family saturate instead, clamping at the limit. This tool clamps, but verify what your code actually compiles to.