在嵌入式中,除法和浮点数的计算都是比较耗时的,因此,对于除法可以用查表法来近似加速。
举例(除以3)如下:
0.333
≈
1
3
0.333≈\frac{1}{3}
0.333≈31
X 1 2 i = 1 3 ( i = 0 , 1 , 2......... m a x i ) \frac{X1}{2^i}=\frac{1}{3} (i=0,1,2.........maxi) 2iX1=31(i=0,1,2.........maxi)
X 2 ( i ) = r o u n d ( 2 i 3 ) X2(i)=round\left(\frac{2^i}{3}\right) X2(i)=round(32i)
e r r o r ( i ) = A b s ( X 2 ( i ) 2 i − 1 3 ) error(i)=Abs\left(\frac{X2(i)}{2^i}-\frac{1}{3}\right) error(i)=Abs(2iX2(i)−31)
j = I n d e x ( m i n ( e r r o r ( i ) ) ) j=Index(min(error(i))) j=Index(min(error(i)))
X = X 2 ( j ) X=X2(j) X=X2(j)
X 2 j ≈ 1 3 \frac{X}{2^j}≈\frac{1}{3} 2jX≈31
注:
m
a
x
i
maxi
maxi的大小确定除法的精度,越大精度越高(如果被除数是2的倍数,则没有误差),但是要防止数值越界。最终我们只取到
X
X
X和
j
j
j就可以用乘法和移位代替除法的计算。
以下,通过Matlab实现不同大小
m
a
x
i
maxi
maxi情况下1到1000的除法,计算
X
X
X和
j
j
j,并显示误差;
clc;clear;
maxlen=1000;
maxi=17;
besti=zeros(1,maxlen);
bestx=zeros(1,maxlen);
for n=1:maxlen
minErr=100000000;
for i=0:maxi
val=(2^i)/n;
%%可添加越界处理
%t=log(val)/log(2);
%if(t+i>32)
% continue;
%end
%%取整
val=round(val);
%%计算误差
err=abs(val/(2^i)-1/n);
%%找误差最小的x,n
if(err<minErr)
bestx(1,n)=val;
besti(1,n)=i;
minErr=err;
end
end
end
%%计算的最佳近似值
N=2.^besti;
calVal=bestx./N;
%%计算的真实值
x=1:maxlen;
trueVal=1./x;
%%求取误差
diff=calVal-trueVal;
figure;
plot(diff,'g');
hold on;
plot(diff,'r*');
title('maxi=17');