快速计算幂(例如 2^11)[重复]
Posted
技术标签:
【中文标题】快速计算幂(例如 2^11)[重复]【英文标题】:Calculating powers (e.g. 2^11) quickly [duplicate] 【发布时间】:2010-02-04 08:07:15 【问题描述】:可能重复:The most efficient way to implement an integer based power function pow(int, int)
如何计算具有更好运行时间的功率?
例如2^13。
我记得在某处看到它与以下计算有关:
2^13 = 2^8 * 2^4 * 2^1
但我看不出如何计算等式右侧的每个分量,然后将它们相乘。
有什么想法吗?
编辑:我的意思是任何基地。您在下面提到的算法,特别是“平方指数”如何提高运行时间/复杂性?
【问题讨论】:
重复:***.com/questions/101439/… “平方指数”以log(exp)
步长计算base^exp
,其中log 是以2 为底的对数。
@Nick D,我知道我在回答中声明了这一点,但我意识到我有点错误。如果您使用标准整数,这基本上是正确的。但是一旦你开始使用 bignums,它基本上就变成了O(log(n)^2)
,因为乘法需要超过 O(1) 的时间。
@Omnifarious,我说的是 log(exp) 步骤,我没有指定 O。我同意你的观点,如果我们考虑“乘法”操作,实际运行时复杂度可能不是 O(logn)。
【参考方案1】:
对此有一个通用算法,但是在具有位移位的语言中,有一种更快的方法来计算 2 的幂。您只需输入 1 << exp
(假设您的位移位运算符是 <<
是支持该操作的大多数语言)。
我假设您正在寻找通用算法并且只是选择了一个不幸的基础作为示例。我将在 Python 中给出这个算法。
def intpow(base, exp):
if exp == 0:
return 1
elif exp == 1:
return base
elif (exp & 1) != 0:
return base * intpow(base * base, exp // 2)
else:
return intpow(base * base, exp // 2)
这基本上导致指数能够以 log2 exp 时间计算。这是一种分而治之的算法。 :-) 正如其他人所说exponentiation by squaring。
如果您将示例插入其中,您可以看到它是如何工作的,并且与您给出的方程式相关:
intpow(2, 13)
2 * intpow(4, 6)
2 * intpow(16, 3)
2 * 16 * intpow(256, 1)
2 * 16 * 256 == 2^1 * 2^4 * 2^8
【讨论】:
【参考方案2】:使用按位移位。前任。 1
【讨论】:
2 仅用作示例库。问题更笼统。【参考方案3】:二的幂是容易的。在二进制中,2^13 是一个 1 后跟 13 个零。
您将使用位移,这是许多语言的内置运算符。
【讨论】:
【参考方案4】:您可以使用exponentiation by squaring。这也称为“平方和乘法”,也适用于基数 != 2。
【讨论】:
链接到***真的很容易,而且我认为***的链接可以很好地补充答案,但***的链接不是答案,除非答案真的太大而无法在这里写下来。 为什么要发明两次***?通常,唯一关键的是找到正确的关键字来命名问题。【参考方案5】:如果您不将自己限制为 2 的幂,那么:
k^2n = (k^n)^2
【讨论】:
【参考方案6】:我所知道的最快的免费算法是Phillip S. Pang, Ph.D
,可以找到源代码here。
它使用表驱动分解,可以使exp()函数比奔腾(R)处理器的本机exp()快2-10倍。
【讨论】:
以上是关于快速计算幂(例如 2^11)[重复]的主要内容,如果未能解决你的问题,请参考以下文章
模幂运算问题,使用朴素算法和重复-平方算法(快速幂+C#计算程序运行时间)