我需要将数字N除以另一个数字D,两者都大于我的字长32位
目前,我正在使用以下算法: http://justinparrtech.com/JustinParr-Tech/an-algorithm-for-arbitrary-precision-integer-division/
我正在实现RISC-V ISA的解决方案
但是在第三步Q = N / A
时,我不知道在余数也是32位数字的情况下该怎么做,因为通常我会将余数用于下一个单词的除法但是如果是寄存器的大小,就不可能考虑到它。
我一直在思考如何解决这个问题,但是我想出的每一个解决方案都不是最好的解决方法。
答案 0 :(得分:4)
那个算法太可怕了。
第一步应该是确定结果的符号(根据分子和除数的符号);然后找到分子和除数的大小(并为“分子为0”和“ abs(除数)为0或1”的捷径,在这种情况下,实际上可以避免或不可能进行除法操作),以便执行实际的除法仅处理正数。
第二步应该是确定除数是否足够小以适合单个数字(数字以您的语言/环境所支持的最大底数为基础-例如对于C的32位整数是“ base 65536”,对于64位80x86汇编语言(可以在其中使用128位分子),它可能是“ base 18446744073709551616”。此时,您将转到两种完全不同的算法之一。
小除数
这是一个相对琐碎的“对于分子中的每个数字{用数字除以除数以找到结果中的数字}”循环(随后固定您在开始时确定的结果的符号)。
大除数
为此,我将使用二进制除法。想法是左右移动分子和除数,以便除数尽可能大而不会大于分子。然后从分子中减去除数,并在结果中设置与您向左/向右移动多少对应的位;并重复此操作,以便(在初始移位之后)最终变成“将分子的剩余部分向左移位;然后与除数比较,如果分子大于除数,则从分子中减去除数并在结果中设置位”当分子没有剩余时终止。
非主题替代
在大多数情况下,您需要任意精度的除法;最好使用有理数,其中每个数存储为三个(任意大小)整数-分子,除数和指数(例如number = numerator/divisor * (1 << exponent)
)。在这种情况下,您不需要除法-您只需乘以倒数。这样不仅可以提高性能,还可以提高精度(例如,您可以计算(1/3) * 6
并保证不会有精度损失)。