单片机浮点数的实用快速降法
4 程序源代码
限于篇幅,只给出源代码中的关键部分,即有效数字的计算部分。
;被除数为x,除数为y
;用yh,hl分别表示y的高16位和低16位
...
;假设x,y的有效数字部分分别在(dx,cx)和(bx,ax)中
;计算预估值Q0'=(x/4)/yh
shrl cx,#2 ;计算x/4
divu cx,bx ;计算(x/4)÷yh
ld fx, cx ;把商暂放入寄存器fx,即Q0'的高16位有 ;效数字
clr cx
divu cx,bx ;把余数末尾添0后面再除以yh
ld ex,cx ;把商暂放入寄存器ex,即Q0'
;的低16位有效数字
;(fx,ex)=Q0'
;计算修正因子 Q1=(yh-yl)/yh
cmp ax,0 ;判断yl是否为0
jne getQ1 ;若yl非0,计算修正因数Q1
ld ax,ex ;若yl=0,修正因数Q1=1
ld bx,fx ;(Q0'×Q1)=Q0',可以直接计算Q
sjmp getQ
getQ1:
ld hx,bx ;把yh放于寄存器hx中
neg ax
dec bx ;计算yh-yl
divu ax,hx ;计算Q1=(yh-yl)÷yh
ld dx,ax ;把商暂时放入寄存器dx,即Q1的高16位有;效数字
clr ax
divu ax,hx ;把余数末尾添0后再除以yh,得Q1的;低16位有效数字
ld bx dx ;(bx,ax)=Q1
;计算Q0'×Q1=(fx,ex)×(bx,ax),只取32位有效数字
ld hx,bx
mulu cx,bx,ex ;(dx,cx)=bx×ex
mulu ax,fx ;(bx,ax)=ax×fx
clr ex
add cx,ax
addc dx,bx
addc ex,0 ;(ex,dx,cx)=(dx,cx)+(bx,ax)
mulu ax,fx,hx ;(bx,ax)=fx×hx
add ax,dx ;(bx,ax)=(bx,ax)+(ex,dx)
addc bx,ex ;(bx,ax)=Q0'×Q1
;计算校准值Q=(Q0' ×Q1)×4并调整阶码
getQ:
...
代码到这里为止,浮点数商的有效数字已经全部求出。只要再执行一些调整浮点数阶码的操作,就可以得到最终结果。
在作者开发的一个80C196KC单片机系统中,涉及到了二进制-十进制数制转换、分段线性插值、数字滤波等大量浮点数的运算,都是靠加减乘除等底层函数来实现的。
此外,本算法思路清晰,因此很容易加以推广。例如,为了得到更高的精度,可取修正因子:
则相对误差,转化为十进制,有效数字高达14位。
评论