【问题标题】:Exponentiation by cyclic shifting通过循环移位求幂
【发布时间】:2013-06-07 17:54:06
【问题描述】:

这里关于 SO 的一些其他主题提到了 Brickell 等人的论文“Fast Exponentiation with Precomputation”,该论文连同与二进制数字对应的幂的预计算的简单概念,有一个关于“循环移位求幂”的声明(如据我了解)。不幸的是,论文的那部分是用一种非常笼统的形式表达的,所以我根本无法弄清楚他们是否在谈论一些明显变得复杂的东西,而不是 2**n,或者真的存在某种其他的求幂方法比乘法(平方)?

例如,假设我们有x = 5(即二进制的00101)。怎么可能以y = 5 * 5(二进制中的11001)结束,只使用位移,也许还有一些加法?当然,算法应该比乘法更有效——答案“你可以通过一堆位移和加法来模拟每个乘法,就像y = (5 << 2) + (5 << 0)”不计算在内。好吧,如果稀疏数字很常见,它可以计算,但这不是常见的情况,并且确定确切的位数也很耗时,所以,除非一个数字 非常 稀疏,否则它不是值得一试,这样每次平方后都需要进行新的评估。

【问题讨论】:

  • 循环移位的事情似乎与 GF(p**n) 中的数学有关。我对此一无所知,除了它可能不适用于普通数学。

标签: algorithm bit-shift discrete-mathematics exponentiation


【解决方案1】:

该方法称为“二进制分解求幂”,您可以在 Knuth 4.6.3 中找到讨论。例如,,因此在第一种情况下您需要 7 次乘法,但在第二种情况下需要 3 次(注意 8 = 100 是二进制的)。执行此操作的代码如下:

long power( int x, int n ){
   long result = 1;
   long base = x;
   while( true ){
      if( n & 1 ) result = base * result;
      n = n >> 1;
      if( n == 0 ) return result;
      base = base * base;
   }
}

【讨论】:

  • 您说的是著名的“平方求幂”,它不使用位移。 n >>= 1 操作只是“整数除以 2”,并不是绝对必要的——您可以通过使用位掩码直接检查特定位来获得相同的结果,这将为您节省一些 CPU 时间,前提是 n也是一个很大的数字。
猜你喜欢
  • 1970-01-01
  • 2016-01-05
  • 1970-01-01
  • 1970-01-01
  • 2018-10-11
  • 1970-01-01
  • 1970-01-01
  • 2018-05-28
  • 1970-01-01
相关资源
最近更新 更多