为什么比乘以两个随机数更快地对数字进行平方?

时间:2009-09-04 05:48:30

标签: algorithm math bit-manipulation discrete-mathematics

将两个二进制数相乘需要n ^ 2次,但是以某种方式可以更有效地对数字进行平方。 (n是比特数)怎么可能?

还是不可能?这是精神错乱!

14 个答案:

答案 0 :(得分:64)

  1. 存在比O(N ^ 2)更有效的算法来乘以两个数字(见Karatsuba,Pollard,Schönhage-Strassen等)

  2. “将两个任意N位数乘以”和“平方任意N位数”这两个问题具有相同的复杂性。

  3. 我们有

    4*x*y = (x+y)^2 - (x-y)^2
    

    因此,如果对N位整数求平均需要O(f(N))时间,那么也可以在O(f(N))中获得两个任意N位整数的乘积。 (即2x N位和,2x N位平方,1x 2N位和,1x 2N位移位)

    显然我们有

    x^2 = x * x
    

    因此,如果乘以两个N位整数取O(f(N)),则可以在O(f(N))中完成N位整数的平方。

    计算产品的任何算法(分别为正方形)提供了一种算法来计算具有相同渐近成本的平方(产品)。

    如其他答案中所述,在平方的情况下,可以简化用于快速乘法的算法。增益将在f(N)前面的常数上,而不在f(N)本身上。

答案 1 :(得分:14)

平方n位数可能比乘以两个随机n位数更快。谷歌搜索我发现this article。它是关于任意精度算术,但它可能与你的要求有关。作者在其中说:

  

平方大整数,即X ^ 2   =(xn-1,xn-2,...,x1,x0)^ 2 xi *形式的许多叉积项   xj和xj * xi是等价的。他们   需要只计算一次然后   左移,以便加倍。   n位数的平方运算是   仅使用(n ^ 2 + n)/ 2执行   单精度乘法。

答案 2 :(得分:7)

正如其他人所指出的那样,平方只能比任意数字之间的常规乘法快约1.5倍或2倍。计算优势来自哪里?它是对称的。让我们计算1011的平方并尝试找出我们可以利用的模式。 u0:u3表示从最重要到最不重要的数字中的位。

    1011 //                               u3 * u0 : u3 * u1 : u3 * u2 : u3 * u3
   1011  //                     u2 * u0 : u2 * u1 : u2 * u2 : u2 * u3       
  0000   //           u1 * u0 : u1 * u1 : u1 * u2 : u1 * u3                 
 1011    // u0 * u0 : u0 * u1 : u0 * u2 : u0 * u3                           

如果您认为ui * ui的元素i=0, 1, ..., 4形成对角线并忽略它们,您会看到ui * uj的元素i ≠ j重复两次。< / p>

因此,您需要做的就是计算对角线以下元素的乘积和,并将其加倍,左移。你最后添加了对角线元素。现在您可以看到2X加速的来源。在实践中,由于对角线和额外操作,加速度约为1.5倍。

答案 3 :(得分:6)

我相信你可能指的是exponentiation by squaring。该技术不用于乘法,而是用于提高功率x ^ n,其中n可能很大。而不是乘以x 时间本身N次,一次执行一系列平方和添加操作,可以映射到N的二进制表示。乘法运算的数量(比大数的加法更昂贵)从N减少到log(N)关于朴素求幂算法。

答案 4 :(得分:4)

你的意思是将数字乘以2的幂?这通常比乘以任意两个随机数更快,因为结果可以通过简单的位移来计算。但是,请记住,现代微处理器将大量的强力硅专用于这些类型的计算,并且与较旧的微处理器相比,大多数算法都以炫目的速度执行

答案 5 :(得分:3)

我拥有它!

2 * 2

2 << 1

(需要注意的是它只适用于一个案例。)

答案 6 :(得分:3)

假设您要扩展乘法(a+b)×(c+d)。它分为四个单独的乘法:a×c + a×d + b×c + b×d

但是如果你想展开(a+b)²,那么它只需要三次乘法(并加倍):a² + 2ab + b²

(另请注意,两个乘法本身是正方形。)

希望这只是开始深入了解在常规乘法上执行正方形时可能出现的一些加速。

答案 7 :(得分:1)

首先是一个很棒的问题!我希望有更多这样的问题。

事实证明,我提出的方法是O(n log n),仅用于算术复杂度的一般乘法。您可以将任何数字X表示为

X = x_{n-1} 2^{n-1} + ... + x_1 2^1 + x_0 2^0
Y = y_{m-1} 2^{m-1} + ... + y_1 2^1 + y_0 2^0

,其中

x_i, y_i \in {0,1}

然后

XY = sum _ {k=0} ^ m+n r_k 2^k

,其中

r_k = sum _ {i=0} ^ k x_i y_{k-i}

这只是FFT的直接应用,用于在(n + m)log(n + m)时间内找到每个k的r_k值。

然后,对于每个r_k,您必须确定溢出的大小并相应地添加它。对于数字的平方,这意味着O(n log n)算术操作。

您可以使用Schönhage-Strassen算法更有效地将r_k值相加,以获得O(n log n log log n)位操作界限。

你的问题的确切答案已由Eric Bainville发布。

但是, 可以获得比O(n ^ 2)更好的约束,因为对于乘法整数存在更好的界限,因此对数字进行平方化!

答案 8 :(得分:0)

如果你假设机器的字长有固定的长度,并且要求平方的数字在内存中,则平方操作只需要一次内存加载,因此可能更快。

对于任意长度的整数,乘法通常为O(N²),但有些算法可以减少大整数。

如果您假设使用简单的O(N²)方法将 a 乘以 b ,则对于 a 中的每个位,您必须移位 b 如果该位为1,则将其添加到累加器。对于 a 中的每个位,您需要3N次移位和添加。

请注意

( x - y )² = x² - 2 xy + y²

因此

x² = ( x - y )² + 2 xy - y²

如果每个 y 是2的最大幂不大于x,则减少到较小的平方,两个移位和两个加法。由于 N 在每次迭代时减少,您可以获得效率增益(对称性意味着它访问三角形中的每个点而不是矩形),但它仍然是O(N²)。

可能还有另一种更好的对称性可供开发。

答案 9 :(得分:0)

A ^ 2 (a + b)*(a + b)+ b ^ 2例如。 66 ^ 2 =(66 + 6)(66-6)+ 6 ^ 2 = 72 * 60 + 36 = 4356

对于^ n只使用幂规则

66 ^ 4 = 4356 ^ 2

答案 10 :(得分:0)

我想通过N位乘法来解决问题

A位是A(n-1)A(n-2)........ A(1)A(0)。

B位是B(n-1)B(n-2)........ B(1)B(0)。

对于数字A的平方,生成的唯一乘法位为 对于A(0)-> A(0).... A(n-1)     A(1)-> A(1).... A(n-1)等 因此总操作将为

OP = n + n-1 + n-2 ....... + 1 因此OP = n ^ 2 + n / 2; 因此渐近符号为O(n ^ 2)

,对于A和B的乘法,将生成n ^ 2个唯一的乘法 因此渐近符号为O(n ^ 2)

答案 11 :(得分:-1)

2 n 的平方根是2 n / 2 或2 n>&gt; 1 ,所以如果你的数字是2的幂,一旦你知道了权力,一切都很简单。倍增甚至更简单:2 4 * 2 8 是2 4 + 8 。你已经在这些陈述中没有任何意义。

答案 12 :(得分:-1)

如果你有一个二进制数A,它可以(总是,证明留给渴望的读者)表示为(2 ^ n + B),这可以平方为2 ^ 2n + 2 ^(n + 1) B + B ^ 2。然后我们可以重复扩展,直到B等于零。我并没有太过刻意,但从直觉上来说,感觉好像你应该能够制作一个平方函数所需的算法步骤比通用乘法更少。

答案 13 :(得分:-4)

我认为你的陈述完全错了

  

乘以两个二进制数   n ^ 2次

将两个32位数乘以一个时钟周期。在64位处理器上,我假设将两个64位数相乘需要1个时钟周期。 32位处理器可以在1个时钟周期内将两个64位数相乘,我甚至不会感到惊讶。

yet squaring a number can be done more efficiently somehow.

平方数只是将数字与自身相乘,所以这只是一个简单的乘法。 CPU中没有“方形”操作。

也许你正在混淆“平方”与“乘以2的力量”。乘以2可以通过将一个位置的所有位移位到“左”来实现。乘以4将所有位两个位置移位到“左”。由8,3个职位。但这个技巧只适用于2的幂。