Libfixmath中Q格式乘法进位逻辑解析及批处理移植疑问
Libfixmath定点数乘法进位逻辑解析
原Q16.16乘法的拆分逻辑
Libfixmath的fix16_mul将两个32位Q16.16定点数拆分为两部分:高16位(含符号与整数部分:A、C)和低16位(小数部分:B、D),本质是把32位数乘法展开为4个16位数的乘积组合,类似十进制两位数乘法的拆分:
[A][B] × [C][D] --------- B×D // 低16位×低16位,结果占32位 C×B // 高16位×低16位,左移16位后对应高32位的低16位 A×D // 低16位×高16位,左移16位后对应高32位的低16位 A×C // 高16位×高16位,结果占高32位
最终64位完整乘积可表示为:(A×C)<<32 + (A×D + C×B)<<16 + B×D。
进位逻辑的本质
代码中product_hi的初始计算AC + (AD_CB >> 16),仅处理了AD_CB的高16位部分,但AD_CB的低16位还需与BD相加,这一步可能产生无符号溢出进位:
ad_cb_temp = AD_CB << 16:将AD_CB的低16位移到32位变量的高16位,与BD(低32位基础值)相加,得到完整的低32位乘积部分product_lo。- 对于无符号整数,若
BD + ad_cb_temp < BD,说明相加结果超出了32位无符号数的最大值(0xFFFFFFFF),此时会有一个值为1的进位被自动丢弃,这个进位属于64位乘积的第32位,必须补充到product_hi中,否则结果会缺失一个2^32的量(对应Q16.16格式的1个整数单位)。
与前置步骤的关联
- 前置步骤中
product_hi仅计算了AC(高32位的基础部分)加上AD_CB的高16位(AD_CB >>16),完全没考虑AD_CB低16位与BD相加产生的进位。 - 这个进位是低32位乘积向高32位的进位,属于最终结果高32位的一部分,必须补充到
product_hi才能得到正确的64位乘积高位值。
Q15.15移植的注意点
你的移植代码逻辑是正确的:
- 拆分时用
0x7FFF提取低15位小数部分,匹配Q15.15的格式定义。 ad_cb_temp = AD_CB <<15将AD_CB的低15位移到对应位置,与BD相加后,同样通过if %product_lo% lss %BD%判断无符号溢出,补充进位到product_hi。- 最终通过
(product_hi <<15) | (product_lo >>15)组合结果,正确提取了Q15.15格式的高15位(符号+整数)和低15位(小数)。
内容的提问来源于stack exchange,提问作者Einstein1969
相关产品推荐
相关产品推荐

