在详细了解算法s、 一些术语:
这个除数是数被分割;例如,在5/7中,除数是5。
这个股息是分部的数量;例如,在5/7中,股息是7。
逻辑左移 卷s为0值一点进入右侧[最不重要]钻头的登记,然后向左滚动[最重要的]咬成一个携带旗帜[滚动所有中间的当然,比特也是如此]。
向左移位滚动携带 旗帜进入右位,然后将左位滚动到进位标志[也滚动所有中间位]。
向左旋转将左位滚动到右位和进入进位旗[滚动所有中间位]。
对于这些代码片段价值除数的是代表通过x个,并被视为米-位值,以及股息是代表由编辑年,并且被认为是n个-钻头值。[通常情况下,米=n个然而,算法更有用越多通用的是的,所以我选择不限制我写的那篇文章特殊情况.]
在做这件事时,需要时刻牢记一个特殊情况任何有点分开是除以0处理该案件的细节留待另一方处理写.本报告的大部分内容涉及将二者分开无符号的值,规则使用签署值在末尾解释。
一种方法划分是由乘法由相互的.[当使用下面描述的方法时,另一种特殊情况是除以1-此方法不会工作时间年为1,因此完整性测试(年=1)和特殊处理琐碎的案例必须添加到下面描述的算法中。]要进行划分x个[存储在米-钻头宽的 登记
A类]由年(年大于1),让L(左)成为第页-位寄存器[第页≥ (米+n个)]包含值(2第页/年)[四舍五入向下]。乘法A类通过L(左),使用米-一点点地第页-位乘法例程,添加 L(左)结果,然后下降最少重要的第页位。[数学上,乘以L(左)然后添加L(左)与相同增量正在计算的值x个之前乘法,但如果x个是(2米-1)则增量会将值推到可代表的 限制寄存器的A类因此,最安全的实施是先乘后加。]这个结果是地板(((X(X)+ 1) *地板(2第页/年)) /2第页),或者简单地说((x个+ 1) /年)带有一舍入误差由“floor”函数引入,最终给出了值地板(x个/年)。只要第页不小于(米+n个),最终舍入误差始终小于1,因此它不会影响结果。这种方法的优点是,某些处理器具有非常快的,硬件实现w个-一点一点地w个-位乘法例程[其中w个是的大小数据字对于特定处理器],因此如果(米+n个) ≤w个然后可以通过扩展登记A类到w个位和通过使用第页=w个.这个通常工作得很好,因为乘法的结果通常存储为两个一半如此下降w个 液化石油气结果中的s通常意味着忽略较低的结果的一半。它的缺点是L(左)必须通过计算划分2第页通过年-所以有些部门必须无论如何,总有一天要完成。此方法最适用于以下情况年可以是固定的在编译时间,所以L(左)是一个常数可以是硬编码的作为一个字面意义的,或其中许多寄存器必须除以相同的值[计算 L(左)一旦使用较慢的除法常规,然后使用更快的乘法例程]。
更多信息传统的除法例程:到分 x个,存储在米-钻头登记 A类,由年,将整数 结果在里面A类以及余数在中n个-位[或更宽]寄存器C,使用一个整数柜台 我用于0到之间的计数米:
C:=0
我:=米
同时(我> 0)
逻辑左移A类
向左移动C
if((进位标志≠0)|(C≥年))然后
C:= (C-年)
A类:= (A类|0x01)
结束条件为
我:= (我- 1)
结束while
在环,最右边我位A类包含地板((x个/年) * (2 ^ (我-米))). [此值保证最多为我位宽,因为x个适合米位,因此小于(2^米)和年≥1,所以((x个/年) * (2 ^ (-米)))小于1。]最左边(米-我)位包含值(x个 国防部(2 ^ (米-我))).
这个实践使用一个寄存器保存两个值最左边的中的位和一个值最右边的位,用于其他算法,如乘法算法在试图理解这样的算法时,记住一个寄存器或变量并不总是对应于一个值。这使得算法更少直观,但这确实让他们更喜欢有效率的就数据 记忆(甚至速度).
将除法的整数结果存储在不同的米-位寄存器,天,并保留A类:
C:= 0
我:=米
同时(我> 0)
逻辑左移天
向左旋转A类
向左移动C
if((进位标志≠0)|(C≥年))然后
C:= (C-年)
天:= (天|0x01)
结尾
我:= (我- 1)
结束while
如果A类无需保留,“向左旋转”A类'可以是替换为“逻辑左移”A类“[在这种情况下A类将包含退出时为0或“左移”A类“[在这种情况下A类将包含之前的内容天退出时]。
固定点除法在某些领域很有用,例如有时人们希望划分和圆到最接近的整数,而不是四舍五入。为此,请使用定点除法比整数除法精度高一位,将结果右移一位place,如果有进位,则递增。每个值都带有分数的一半的价值或更大的值将向上取整,所有其他值将向下取整。要执行定点除法,程序员希望得到o个位,和o个>米,输入结果天[现在o个位宽],则可以使用以下算法:
C:= 0
我:=o个
同时(我> 0)
逻辑左移天
逻辑左移A类
向左移位C
if((进位标志≠0)|(C≥年))然后
C:= (C-年)
天:= (天|0x01)
结束条件为
我:= (我- 1)
结束while
A类将被清除。
保存A类,可以使用额外的寄存器[E类, (o个-米)位宽]:
E类:= 0
C:= 0
我:=o
同时(我> 0)
逻辑向左移位天
向左旋转A类:E类
向左移位C
if((进位标志≠0)|(C≥年))然后
C:=(C-年)
天:= (天|0x01)
结束条件为
我:= (我- 1)
结束while
'向左旋转A类:E类'可以通过以下方式完成:
逻辑向左移位E类
向左移位A类
如果(进位标志≠0),则
E类:= (E类|0x01)
结束条件为
E类将在本次例行程序结束时清除。
定点除法o个<米在我的经历中是罕见的,然而,对于完整性,这里有一个算法[使用寄存器E类,这是o个位宽]:
E类:=[最重要o个位x个]
C:= 0
我:=o个
同时(我> 0)
逻辑左移E类
向左旋转C
向左移位C
if((进位标志≠0)|(C≥年))然后
C:= (C-年)
天:= (天|0x01)
结尾
我:= (我-1)
结束while
E类在出口处是安全的。[如果A类不需要保存,寄存器E类可以去掉和“逻辑左移”E类'可以替换带有“向左旋转”A类','逻辑左移A类',或'左移A类'.]
回到乘倒数的方法,以下算法将除以2第页通过年,将结果放入第页-位宽寄存器天,提供了年不是1:
C:= 1
我:=第页
同时(我> 0)
逻辑左移天
逻辑左移C
if((进位标志≠0)|(C≥年))然后
C:= (C-年)
天:= (天|0x01)
结束条件为
我:= (我- 1)
结束while
要进行划分签署值,首先确定签名结果(如果除数和股息如果相同,则结果的符号为+;如果标志是不同的是,结果的符号是-)。接下来,根据需要转换除数和股息分配给非负的值。执行无符号除法,然后应用第一步中确定的结果。如果四舍五入到最接近的值,应小心有符号除法中的整数-例如,7.5通常舍入为8,而-7.5通常舍入到-7。如果可以接受从-7.5到-8的四舍五入,那么不用担心;否则,适当的值应如下表所示。R(右)表示来自的结果无符号除法,C是C在后面注册部门:
\结果为+ve结果为-ve\ ((2 *C) <年)R(右)-R(右)((2 *C) =年) (R(右)+ 1) -R(右)((2 *C) >年) (R(右)+ 1) -(R(右)+ 1)
最后,值得注意的是,上述除法示例都不是可重入的.通常,很难使除法例程可重入,最简单的方法是可能会有地方的 影像寄存器对于每个实例佛罗伦萨的复制品短时间内例程开始时被除数和除数的值批评的部分(即带有打断秒禁用),处理影子寄存器,然后将结果复制回批评的 部分在…的末尾例行程序。