Algorithm 为什么一个数的平方比两个随机数的乘积快?

Algorithm 为什么一个数的平方比两个随机数的乘积快?,algorithm,math,bit-manipulation,discrete-mathematics,Algorithm,Math,Bit Manipulation,Discrete Mathematics,将两个二进制数相乘需要n^2的时间,然而,以某种方式将一个数平方可以更有效地完成。(n是位数)这怎么可能 还是不可能?这太疯狂了 你是说一个数字乘以2的幂吗?这通常比任何两个随机数相乘要快,因为结果可以通过简单的位移位来计算。但是,请记住,现代微处理器将大量强力硅用于这些类型的计算,与旧微处理器相比,大多数算法的执行速度都非常快,2n的平方根是2n/2或2n>>1,因此,如果您的数字是2的幂,那么一旦知道幂,一切都非常简单。乘法更简单:24*28是24+8。你所做的这些陈述毫无意义。我相信你可能

将两个二进制数相乘需要n^2的时间,然而,以某种方式将一个数平方可以更有效地完成。(n是位数)这怎么可能


还是不可能?这太疯狂了

你是说一个数字乘以2的幂吗?这通常比任何两个随机数相乘要快,因为结果可以通过简单的位移位来计算。但是,请记住,现代微处理器将大量强力硅用于这些类型的计算,与旧微处理器相比,大多数算法的执行速度都非常快,2n的平方根是2n/2或2n>>1,因此,如果您的数字是2的幂,那么一旦知道幂,一切都非常简单。乘法更简单:24*28是24+8。你所做的这些陈述毫无意义。

我相信你可能指的是。这项技术不是用于乘法,而是用于提高到x^n的幂,其中n可能很大。而不是乘以x 乘以N次,执行一系列平方运算和加法运算,这些运算可以映射到N的二进制表示形式。相对于朴素指数算法,乘法运算(比大数加法更昂贵)的数量从N减少到log(N)

我拿到了

2 * 2
它比其他任何东西都贵

2 << 1

2我认为你的话完全错了

将两个二进制数相乘需要 n^2次

两个32位数字相乘正好需要一个时钟周期。在64位处理器上,我假设两个64位数字相乘正好需要1个时钟周期。32位处理器可以在一个时钟周期内将两个64位数字相乘,这一点都不奇怪

yet squaring a number can be done more efficiently somehow.
求一个数的平方就是将该数与其自身相乘,所以这只是一个简单的乘法。CPU中没有“方形”操作


也许你把“平方”和“乘以2的幂”混淆了。通过将所有位移到“左”一个位置,可以实现乘以2。乘以4就是将所有位移到“左”的两个位置。8,3个位置。但是这个技巧只适用于二的幂。

将一个n位数平方可能比将两个随机n位数相乘更快。我在谷歌上找到了。这是关于任意精度的算术,但它可能与你的要求有关。作者在书中说:

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


如果你有一个二进制数a,它可以(总是,留给热切的读者去证明)表示为(2^n+B),它可以被平方为2^2n+2^(n+1)B+B^2。然后我们可以重复展开,直到B等于零。我没有仔细研究过它,但直觉上,它感觉好像你应该能够使平方函数比通用乘法用更少的算法步骤。

如果你假设机器的字长是固定的,并且要平方的数字在内存中,平方运算只需要从内存加载一次,因此速度可能更快

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

如果采用简单的O(N²)方法将a乘以b,那么对于a中的每一位,必须移动b并将其添加到累加器中(如果该位为1)。对于a中的每一位,您需要3个移位和加法

注意

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

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

也许还有另一个更好的对称性可以利用

  • 有比O(N^2)更有效的两个数相乘的算法(见Karatsuba、Pollard、Schönhage–Strassen等)

  • “两个任意N位数字相乘”和“任意N位数字平方”这两个问题具有相同的复杂性

  • 我们有

    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)),那么N位整数的平方可以在O(f(N))中完成

    任何计算乘积(即平方)的算法都提供了一种以相同的渐近代价计算平方(即乘积)的算法


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

    首先是一个伟大的问题!我希望有更多这样的问题

    结果证明,我提出的方法是O(n logn),只用于算术复杂度的一般乘法。可以将任意数字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
    
    在哪里

    然后

    在哪里

    这只是FFT的一个直接应用程序,用于查找(n+m)对数(n+m)时间中每个k的r_k值

    然后,对于每个r_k,您必须确定溢出量有多大,并相应地将其相加。对于一个数的平方,这意味着O(n logn)算术运算

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

    Eri已经发布了您问题的确切答案
    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}
    
        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