一、来源
Q 格式的 "Q" 最早源于 TI 的定点数表示法,ARM 在 CMSIS 中标准化,成为嵌入式定点运算的通用规范。
Q 格式是嵌入式领域的定点数表示方法 ,本质是用整数来模拟小数运算 ------ 通过预先约定小数点在二进制数中的固定位置,让普通整数具备表示小数的能力。
对比易理解的浮点数(如 float/double),Q 格式的核心是 "定点":小数点位置一旦约定就不再改变,而浮点数是"浮点":小数点位置随指数位动态变化。
浮点数的二进制存储科普:
一、先从十进制科学计数法入手:指数和尾数的通俗类比
我们平时用的十进制科学计数法,就是把任意数拆成「尾数 + 指数」的形式,这是浮点数指数 / 尾数的原型:
通用形式:
数值尾数基数指数
- 十进制基数是10 ,二进制浮点数基数是2;
- 尾数 :表示数的有效数字,通常归一化为「1.xxxxx」的形式(保证精度最高);
- 指数 :表示小数点的移动位数 / 缩放倍数,正指数右移小数点,负指数左移小数点。
直观例子:
- 123.45=1.2345×102 → 尾数 = 1.2345,指数 = 2(小数点右移 2 位);
- 0.00105=1.05×10−3 → 尾数 = 1.05,指数 =-3(小数点左移 3 位);
- 5=1.0×101 → 尾数 = 1.0,指数 = 1(整数也归一化)。
核心 :尾数决定数的精度,指数决定数的大小 / 小数点位置,浮点数的二进制存储,就是把这个逻辑搬到二进制中,并做了硬件适配的优化。
二、二进制浮点数的指数和尾数(以嵌入式最常用的32 位单精度 float为例)
32 位 float 是 IEEE 754 标准的核心类型,嵌入式 MCU(STM32/N32 等)的浮点数均遵循此标准,它将 32 位二进制严格划分为 3 部分,其中后两部分就是指数和尾数,整体结构:
plaintext
32位float:[符号位(S)·1位] + [指数位(E)·8位] + [尾数位(M)·23位]各部分作用(结合二进制科学计数法):
二进制浮点数的通用表示公式:数值逐个拆解符号位、指数位、尾数位 的实际含义,重点讲指数 和尾数:
1. 符号位(S):仅表示正负,和指数 / 尾数无关
- S=0 → 正数,S=1 → 负数;
- 作用:通过(−1)S实现正负表示,无需给指数 / 尾数单独加符号位,简化硬件设计。
2. 指数位(E):8 位无符号数,代表二进制的指数偏移量
浮点数的实际指数 并非直接存指数位的二进制值,而是做了 **+127 的偏移 **(也叫偏置值 ,8 位指数的偏置值固定为 127),原因是为了用无符号数表示正负指数(硬件处理无符号数更高效)。
- 实际指数 真实存储的指数位二进制值;
- 指数位范围:0~255 → 实际指数范围:−127 +128;
- 作用:决定二进制小数点的浮动位置,对应十进制科学计数法中「10 的几次方」,是浮点数 "浮点" 的核心。
3. 尾数位(M):23 位无符号数,代表二进制尾数的小数部分
这是最容易理解偏差的点:浮点数的尾数采用 **「隐藏最高位 1」的归一化设计(也叫 隐含位 **),目的是用 23 位存储 24 位有效精度,提升硬件利用率。
- 二进制尾数的完整形式是 1.M(1 是隐藏位,M 是尾数位的 23 位小数);
- 尾数位 M 的范围:000...000 ~ 111...111 → 完整尾数范围:1.000...000 1.111...111(二进制);
- 作用:表示数的有效二进制数字 ,尾数位的位数决定浮点数的精度(23 位 + 1 位隐藏位 = 24 位有效精度)。
二、为什么需要Q格式?
Q 格式的诞生完全是为了适配嵌入式 MCU 的硬件特性,解决浮点数在嵌入式场景中的致命问题,这也是 ARM 官方为 Cortex-M 系列专门定义 Q 格式的原因,核心解决的问题有 3 个:
痛点 1:多数低端 MCU 无硬件浮点单元(FPU),浮点数运算效率极低
Cortex-M0/M0+/M3等低端 MCU无硬件 FPU ,浮点数(float/double)运算完全依靠软件模拟 ------ 编译器将浮点数运算拆解为数十条整数运算指令,耗时是整数运算的几十倍甚至上百倍。
而 Q 格式本质是整数运算 :所有 Q 格式的小数计算,最终都能转换为普通的整数加减乘除,仅需在运算后根据 Q 格式规则做简单的移位 / 归一化,运算效率和整数完全一致,无需任何硬件 FPU 支持。
痛点 2:浮点数占用更多内存,不符合嵌入式 "资源紧缺" 的特点
- 浮点数(float)占4 字节 ,double 占8 字节;
- Q15 仅占2 字节,Q31(32 位定点数,31 位小数)也仅占 4 字节,和 float 相同但运算效率更高。
嵌入式 MCU 的 RAM/Flash 通常以 KB 为单位(如 STM32F103 仅 20KB RAM、64KB Flash),Q 格式能大幅节省内存占用,尤其适合批量存储数据(如 Q15 正弦表 256 点仅 512 字节)。
痛点 3:浮点数的 "非确定性",不适合嵌入式实时控制系统
浮点数运算存在精度漂移、舍入误差不可控 的问题,且软件模拟的浮点数运算耗时不固定(不同数值的运算指令数不同)。
而嵌入式实时系统(如电机 FOC、工业控制、信号调制)对运算耗时的确定性 和精度的可预测性要求极高:
- Q 格式的误差是量化误差(由小数位位数决定,如 Q15 的量化步长1/32767≈3.05×10−5),固定且可预测;
- Q 格式运算的耗时完全固定,和运算数值无关,能保证实时系统的时序稳定性。
三、ARM CMSIS-DSP Q格式定义
Q 完整格式表示为:Qm.n,表示数据用 m 比特表示整数部分,n 比特表示小数部分,共需要 m+n+1 位来表示这个数据,多余的一位用作符合位。
ARM CMSIS-DSP中,一般整数部分m都是0,因此,一般简记为Qn。
所有 Q 格式均为有符号数 ,最高位固定为符号位(0 正 1 负),剩余位数按 Qn 表示n 位小数的定点数格式,如 Q7=7 位小数,Q15=15 位小数,Q31=31 位小数;

Qn 格式的实际物理值 = 整数存储值 / 2^n;
Q15 的实际值 = 存储值 / 2^15 = 存储值 / 32768(注:因有符号数补码特性,实际用 32767 近似,误差可忽略);
Q7 的实际值 = 存储值 / 2^7 = 存储值 / 128。
ref: