2. 定点数表示与算术基础
定点化设计的第一步,不是急着把 Simulink 模型里的 double 改成 fixdt,而是先弄清楚一个数在硬件里究竟长什么样。定点数的本质,是用有限位宽去近似实数:字长决定能表示多少种取值,小数位决定这些取值之间的间隔,符号位决定是否要留出一半编码给负数。三者一旦确定,一个数的表示范围与分辨率就同时被锁死,后续的加减乘除、溢出、舍入和饱和,全部是在这个约束下展开的。
字长、小数位与符号位
一个定点数通常写成 fixdt(1,16,12) 这样的形式,含义是:有符号(1)、总字长 16 位、小数位 12 位。总字长 WL 决定编码空间大小,小数位 FL 决定二进制小数点落在哪一位,符号位则决定最高位是权值还是补码符号。对二进制补码有符号数,其可表示范围为
范围 = [-2^(WL-1), 2^(WL-1) - 2^(-FL)]
分辨率(LSB) = 2^(-FL)
以 fixdt(1,16,12) 为例:WL=16、FL=12,则 LSB = 2⁻¹² ≈ 0.000244,范围约为 [-8, 7.999756]。若改成 fixdt(1,16,8),LSB 变为 2⁻⁸ ≈ 0.003906,范围扩大到约 [-128, 127.996]。可以看到,字长不变时,小数位越多,分辨率越细,但动态范围越小;小数位越少,范围越大,但量化台阶越粗。这就是定点设计中最核心的“精度—范围”权衡。
无符号数则把全部 WL 位都用于表示非负值,范围为 [0, 2^WL − 2^(−FL)]。在 Simulink 中,fixdt(0,8,4) 表示无符号、8 位、4 位小数,LSB = 0.0625,范围 [0, 15.9375]。选择有符号还是无符号,取决于物理量本身是否可能为负,例如温度偏差可能为负,而计数器、索引通常用无符号。
Q 格式与斜率-偏置表示
Q 格式是定点表示的另一种常见记法,Qm.n 表示有 1 位符号、m 位整数、n 位小数,总字长 WL = 1 + m + n。例如 Q3.12 对应 WL = 16、FL = 12,与 fixdt(1,16,12) 等价。Q 格式的优点是直观:看到 Q3.12 就知道整数部分有 3 位、小数部分有 12 位,范围与分辨率可以心算出来。工程中常说的“Q15 格式”,指 Q0.15,即 16 位有符号、15 位小数,范围约 [-1, 0.99997],是音频、滤波器系数等归一化信号的常用格式。
当定点数需要表示带物理单位的量时,更通用的是斜率-偏置表示:
真实值 = 斜率 × 存储整数 + 偏置
斜率 = 2^(-FL),偏置通常为 0
Simulink 的 fixdt(Signed, WordLength, FractionLength) 默认偏置为 0,斜率由小数位隐含给出。若使用 fixdt(Signed, WordLength, Slope, Bias),则可以显式指定斜率与偏置,例如把 0~5V 的 ADC 码值映射为 0~100℃ 的温度,斜率 = 100/255,偏置 = 0。斜率-偏置表示让定点数不再局限于二进制小数,而是可以直接承载工程量纲,这在传感器标定与执行器输出中非常实用。
定点加减乘除的数学本质
定点加法要求两个操作数的小数点对齐,即 FL 相同。若 FL 不同,需要先做对齐:把 FL 较小的数左移若干位,使其 FL 与较大的数一致,同时字长相应增加。例如 fixdt(1,16,12) 与 fixdt(1,16,8) 相加,需把后者左移 4 位变成 fixdt(1,20,12),再与前者相加,结果字长至少 21 位才能避免溢出。Simulink 的 Sum 模块在定点模式下会自动推导输出类型,但设计者必须清楚:加法结果的整数位是两操作数整数位的最大值加 1,小数位取两者中的较大值。
定点乘法的小数位是两操作数小数位之和,字长是两者字长之和。例如 fixdt(1,16,12) 乘 fixdt(1,16,12),理想结果需要 32 位字长、24 位小数。若最终只保留 16 位、12 位小数,就必须做舍入或截断,并可能伴随溢出。乘法是定点设计中位宽增长最快的运算,也是后续“量化误差”和“溢出”问题的主要来源。
除法在定点中通常不直接实现,而是转化为“乘以倒数”或使用移位近似。若必须做除法,结果的小数位 = 被除数小数位 − 除数小数位 + 精度补偿位,字长也相应增加。工程上更常见的做法是:把除法放在浮点域完成,或预先计算好倒数系数并以 Q 格式存储,再用乘法实现。
溢出、舍入与饱和
溢出发生在结果超出目标字长可表示范围时。二进制补码的溢出表现为“回绕”:例如 fixdt(1,8,4) 的最大值 7.9375 再加 0.0625,结果会变成 −8.0,而不是 8.0。这种回绕在控制系统中极其危险,可能让执行器从最大输出瞬间跳到反向最大。Simulink 中可通过 Saturation 模块或定点属性中的“Saturate on overflow”选项,把溢出结果钳位到最大/最小值,代价是引入非线性。
舍入发生在结果小数位多于目标小数位时。常见模式有:
- Floor(向下取整):直接丢弃多余位,误差恒为负,实现最简单,但会引入直流偏置。
- Round(最近舍入):向最近的量化台阶取整,误差在 ±0.5 LSB 内,无偏置,是 Simulink 定点默认舍入方式。
- Convergent(收敛舍入):遇到正好半格时向偶数方向取整,进一步减小统计偏差,适合长时间累加场景。
舍入与饱和往往同时出现:先舍入到目标小数位,再判断是否溢出并饱和。Simulink 的定点数据类型属性中,RoundingMethod 与 OverflowAction 正是分别控制这两步。理解它们的数学本质,才能在模型里做出有依据的选择,而不是默认全用 Round + Saturate。
fixdt 推导结果核对。一个可复用的参数速查表
下表给出几种典型 Q 格式的范围与分辨率,便于在选型时快速对照。表中数值为按公式计算的理论值,实际使用时还需结合具体信号动态范围留出余量。
| Q 格式 | fixdt 表示 | 字长 | 小数位 | LSB | 范围 |
|---|---|---|---|---|---|
| Q0.15 | fixdt(1,16,15) | 16 | 15 | ≈3.05e-5 | [-1, 0.99997] |
| Q3.12 | fixdt(1,16,12) | 16 | 12 | ≈2.44e-4 | [-8, 7.99976] |
| Q7.8 | fixdt(1,16,8) | 16 | 8 | ≈3.91e-3 | [-128, 127.996] |
| Q15.0 | fixdt(1,16,0) | 16 | 0 | 1 | [-32768, 32767] |
| UQ4.4 | fixdt(0,8,4) | 8 | 4 | 0.0625 | [0, 15.9375] |
掌握这些基础后,再回到 Simulink 中设置信号的数据类型,就不会只是机械地填写 fixdt 参数,而是能预判每一步运算的位宽增长、精度损失和溢出风险。定点化的核心不是“把浮点换成定点”,而是在范围、精度、位宽和运算代价之间做出可解释、可验证的工程取舍。