实数除法的一种快速实现方法
说明:本文主要根据如下链接的文章改写整理而成,框图及代码均为原文作者提供,版权归原文作者所有。有版权问题请联系博主。
http://ieeexplore.ieee.org/xpl/articleDetails.jsp?tp=&arnumber=5888664&contentType=Journals+%26+Magazines&queryText%3DMultiplier-Free+Divide%2C+Square+Root%2C+and+Log+Algorithms
嵌入式芯片运算处理单元一般都有加法器,有的还有专门的乘法器,但都没有除法器。这里介绍一种实数除法的实现方法。这种方法在计算实数除法的时候,甚至都不需要乘法运算,效率非常高。
一、基本思路
假定计算x=b/a,其中b和a均为实数,且a不为0。基本思路是先构造一个函数:
J(x) = ax^2-2bx (1)
这是因为对上式求导可得
D(x) = dJ(x)/dx = 2ax-2b (2)
当D(x)为0时,x的取值正好就是所要求的b/a。
于是,我们就可以先给定一个x的初始值,在(2)的约束条件下,通过迭代的方式使得D(x)趋于0,从而求解b/a。
二、实现原理
先给定x0 = 0,此时d0 = D(x0) = -2b。假定迭代步长为h,则x1的取值在x0+h与x0-h之间,并要保证J(x1)
a*h, then J(x0-h) 写成更一般的形式,已知xn和dn = D(xn),则判断:
If dn<-a*h, then J(xn+h)a*h, then J(xn-h)若满足(5)式,则xn := xn+h,此时dn:=dn+2ah; 若满足(6)式,则xn := xn-h,此时dn:=dn-2ah;若既不满足(5)式,也不满足(6)式,则将步长h调整为原来步长的一半,即h := h/2, 再进行(5)式及(6)式的判断。以此类推,逐步迭代。
三、实现框图
上述算法的实现框图如图1所示。参数a,b,h的含义已经介绍过了,Nbits是结果的精度要求,用来作为迭代的终止条件。比如要求除法结果的精度为小数点后8位,则Nbits选为8即可。若要求精确到64位,则Nbits = 64。
这个算法能快速实现的关键在于参数h的选择,因为运算过程中需要多次对h的运算。将h选为2的幂次方,则对h的乘法运算a*h可用移位来实现,这样可以极大地提高效率。
图1 实现框图
四、matlab实现代码
下面给出的是上述算法的matlab实现代码。
function [x,k,Trajectory]=dcd_real_division(a,b,h_init,Mb,Nu)
% [x,k,Trajectory]=dcd_real_division(a,b,H,Mb,Nu)
% multiplication-free division of b by a
% using the algorithm proposed by Liu, Weaver and Zakharov
%
% h_init is the initial value of h (should be a power of two)
% Mb is the number of bits used to code x
% Nu is the maximal number of successfull iterations.
%
% Trajectory variable is computed only for algorithm characterization.
%
% Francois Auger, Luo Zhen, april-july 2010
if (a==0)
error('a should not be equal to zero');
elseif (a<0)
a=-a; b=-b; % change both signs
end;
k=0; m=1; x=0; h=h_init;
Dx=-2*b; a_times_h=a*h_init; % left or right shifts
if (nargout>=3),
Trajectory(:,1)=[x;a*x^2-2*b*x];
end;
while (m<=Mb)&(k<=Nu),
while (abs(Dx)> a_times_h)
if (Dx < 0.0)
x=x+h; Dx=Dx + 2 * a_times_h; % left shift
else
x=x-h; Dx=Dx - 2 * a_times_h; % left shift
end;
k=k+1;
if (nargout>=3),
Trajectory(:,k+1)=[x;a*x^2-2*b*x];