x86汇编8.8定点数除以Pi运算精度不足问题求助
问题解决思路与优化代码
首先明确8.8定点数的运算规则:寄存器AX中存储的整数值 = 真实物理值 * 256,你需要实现的运算逻辑为:输出AX值 = 输入AX值 / π。
原有代码的问题
- 被除数初始化错误:16位
div指令执行的是DX:AX32位值除以16位寄存器的操作,你仅给DL赋值,DH未清零,导致高8位是随机值,被除数完全错误。 - 除数精度不足:你用的804是π*256≈804.2477的截断值,固有误差较大,最终结果精度不够。
- 运算方式选择不合理:同等位宽下,定点乘法的精度远高于除法,且不会出现除法溢出问题。
推荐方案:用倒数乘法提升精度
我们可以把除以π转换为乘以1/π的定点近似值,大幅提升运算精度:
- 1/π≈0.318309886,将其放大2^16倍得到近似整数值
20861,误差小于0.000004 - 16位乘法得到32位结果后,右移16位即可得到目标值,完全符合8.8定点数的精度要求
无符号8.8定点数代码
mov bx, 20861 ; (1/π) * 2^16 的近似整数值 mul bx ; 32位结果存在DX:AX中,等价于 AX * 20861 mov ax, dx ; 右移16位得到最终的8.8定点结果
有符号8.8定点数代码
如果你的输入是有符号数,只需把mul换成有符号乘法指令imul即可:
mov bx, 20861 imul bx mov ax, dx
原有除法方案的修正
如果必须使用除法实现,只需要修正DX初始化问题,可小幅提升精度:
mov dx, 0 ; 先把DX整体清零 mov dl, ah ; 被除数左移8位,得到32位值 = 输入AX * 256 mov ah, al mov bx, 804 ; 可替换为805,根据你的测试用例误差偏好调整 div bx
该方案的精度依然低于乘法方案,仅做兼容性参考。
内容的提问来源于stack exchange,提问作者Alp Karaagac
相关产品推荐
相关产品推荐

