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。斜率-偏置表示让定点数不再局限于二进制小数,而是可以直接承载工程量纲,这在传感器标定与执行器输出中非常实用。

定点数位域结构与 Q 格式对应关系 fixdt(1,16,12) / Q3.12 S 整数位 m=3 小数位 n=12(LSB = 2⁻¹² ≈ 0.000244) 范围 ≈ [-8, 7.999756] 分辨率 ≈ 0.000244 fixdt(0,8,4) / UQ4.4 整数位 m=4 小数位 n=4(LSB = 0.0625) 范围 [0, 15.9375] 分辨率 0.0625 斜率-偏置表示 真实值 = 斜率 × 存储整数 + 偏置 (斜率 = 2⁻ᶠᴸ,偏置默认 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。

判断一个定点运算是否需要扩位,可以按“整数位取最大加一、小数位取最大、乘法位宽相加”的口诀快速估算,再结合 Simulink 的 fixdt 推导结果核对。

一个可复用的参数速查表

下表给出几种典型 Q 格式的范围与分辨率,便于在选型时快速对照。表中数值为按公式计算的理论值,实际使用时还需结合具体信号动态范围留出余量。

Q 格式 fixdt 表示 字长 小数位 LSB 范围
Q0.15fixdt(1,16,15)1615≈3.05e-5[-1, 0.99997]
Q3.12fixdt(1,16,12)1612≈2.44e-4[-8, 7.99976]
Q7.8fixdt(1,16,8)168≈3.91e-3[-128, 127.996]
Q15.0fixdt(1,16,0)1601[-32768, 32767]
UQ4.4fixdt(0,8,4)840.0625[0, 15.9375]

掌握这些基础后,再回到 Simulink 中设置信号的数据类型,就不会只是机械地填写 fixdt 参数,而是能预判每一步运算的位宽增长、精度损失和溢出风险。定点化的核心不是“把浮点换成定点”,而是在范围、精度、位宽和运算代价之间做出可解释、可验证的工程取舍。