实数除法的一种快速实现方法

实数除法的一种快速实现方法

说明:本文主要根据如下链接的文章改写整理而成,框图及代码均为原文作者提供,版权归原文作者所有。有版权问题请联系博主。

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)<J(x0)。这点通过下面的条件来保证:

                If d0<-a*h, then J(x0+h)<J(x0)    (3)

                If d0>a*h, then J(x0-h)<J(x0)     (4)

若满足(3)式,则x1 = x0+h,此时d1=D(x1)=d0+2ah; 若满足(4)式,则x1 = x0-h,此时d1=D(x1)=d0-2ah;若既不满足(3)式,也不满足(4)式,则将步长h调整为原来步长的一半,即h := h/2, 再进行(3)式及(4)式的判断。

        写成更一般的形式,已知xn和dn = D(xn),则判断:

                If dn<-a*h, then J(xn+h)<J(xn)    (5)

                If dn>a*h, then J(xn-h)<J(xn)     (6)

若满足(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]; 

你可能感兴趣的:(Algorithm,算法,function,matlab,嵌入式,2010)