现在的位置: 首页 > 综合 > 正文

大整数乘法

2018年11月08日 ⁄ 综合 ⁄ 共 1329字 ⁄ 字号 评论关闭

通常,在分析一个算法的计算复杂性时,都将加法和乘法运算当作是基本运算来处理,即将执行一次加法或乘法运算所需的计算时间当作一个仅取决于计算机硬件处理速度的常数。这个假定仅在参加运算的整数能在计算机硬件对整数的表示范围内直接处理时才是合理的。然而,在某些情况下我们要处理很大的整数,它无法在计算机硬件能直接表示的整数范围内进行处理。若用浮点型来表示它,则只能近似地表示它的大小,计算结果中的有效数字也受到限制。若要精确地表示大整数并在计算结果中要求精确地得到所有位数上的数字,就必须用软件的方法来实现大整数的算术运算。

设X和Y都是n位的二进制整数,现在要计算它们的乘积XY。我们可以用小学所学的方法来设计一个计算乘积XY的算法,但是这样做计算步骤太多,显得效率较低。如果将每两个一位数的乘法或加法看做一步运算,那么这种方法要进行O(n2)步运算才能求出乘积XY。下面我们用分治法来设计一个更有效的大整数乘积算法。

我们将n位的二进制整数X和Y都分为2段,每段的长为n/2(为了简单起见,假设n是2的幂)

由此,X = A2n/2 + B, Y = C2n/2 +D. 这样,X和Y的乘积为:

XY= (A2n/2 + B) ( C2n/2 +D) = AC2n +(AC+BD) 2n/2+BD

         如果按此式计算XY,则我们必须进行4次n/2位整数的乘法(AC,AD,BC和BD),以及3次不超过2n位的整数加法(分别对应式中的加号),此外还要做2次移位(分别对应于式中乘2n和乘2n/2)。所有这些加法和移位共用O(n)步运算。设T(n)是2个n位整数相乘所需的运算总数,则我们有:

由此可得T(n)=O(n2).因此,直接用此式来计算X和Y的乘积并不比小学生的方法更有效。要想改进算法的计算复杂性,必须减少乘法次数。下面我们把XY写成另一种形式:

XY= (A2n/2 + B) ( C2n/2 +D) = AC2n +((A-B)(D-C)+AC+BD)2n/2+BD

此式看起来似乎更复杂些,但它仅需做3次n/2位整数的乘法(AC,BD和(A-B)(D-C)),6次加减法和2次移位。由此可得:

容易求得其解为T(n) = O(nlog3)=O(n1.59)。这是一个较大的改进。

上述二进制大整数乘法同样可应用于十进制大整数的乘法以减少乘法次数,提高算法效率。

如果将大整数分成更多段,用更复杂的方式把它们组合起来,将有可能得到更优的算法。

最终的,这个思想导致了快速傅利叶变换(Fast Fourier Transform)的产生。该方法也可以看作是一个复杂的分治算法。

快速傅里叶变换的要点如下:一个界长为 N 的离散傅里叶变换可以重新写成两个界长各为 N/2 的离散傅里叶变换之和。其中一个变换由原来 N 个点中的偶数点构成,另一个变换由奇数点构成。这个过程可以递归地进行下去,直到我们将全部数据细分为界长为 1 的变换。什么是界长为 1 的傅里叶变换呢?它正是把一个输入值复制成它的一个输出值的恒等运算。要实现以上算法,最容易的情况是原始的 N 为 2 的整幂次项,如果数据集的界长不是 2 的幂次时,则可添上一些零值,直到 2 的下一幂次。在这个算法中,每递归一次需 N
阶运算,共需要 log N 次递归,所以快速傅里叶变换算法的时间复杂度是 O(N logN)。

【上篇】
【下篇】

抱歉!评论已关闭.