执行取幂的最快算法是什么?为简单起见,我们假设自然数字基数和指数。
高效的数学库会用什么?
(当我搜索它时,我只得到与指数时间内运行的算法相关的结果。)
答案 0 :(得分:3)
上述所有二进制方法的问题在于它们仅限于整数。如果通过"指数"你的意思是计算e ^ x函数,我看到的最好的是快速收敛的幂级数,以及在有限范围内有效的多项式,有理或Pade近似。
有一件事是肯定的:如果你发现e ^ x到96位小数点的闪电般快速算法,你也会发现一种更快的计算日志的方法(由Newton-Raphson提供)。实际上,Newton-Raphson以二次方式收敛,因此每次迭代时,日志中精度的位数加倍。这是加州大学洛杉矶分校Nate Grossman在Forth时代的最爱。
回到四手计算器的时代,我习惯使用e ^ x =(1 + x / 1024)^ 10。当然,对于x非常大或非常小的分解,但你可以看到它的工作原理。如果你有一个平方根按钮,你可以改变这个想法来获得对数。但是你不需要指数函数的平方根。
我想知道AGM算法是否有一些可以做指数函数的反演...嗯......
答案 1 :(得分:2)
对于小指数,Python使用二进制求幂(一种通过平方求幂),如http://svn.python.org/view/python/trunk/Objects/longobject.c?view=markup&pathrev=65518的第2874行所示
对于较大的指数,它使用2 ^ 5-ary取幂(通过平方取代的另一种取幂)。
如果您只关心结果的最高位数,那么您可以非常快速地计算x ^ y = exp(y * log(x))。
如果您只关心结果的最低有效位(例如编程竞赛),那么您可以计算模数为M的指数。例如,Python命令pow(x,y,1000)将计算x的最后3位数到y的幂。它通过平方方法取幂来做到这一点,但请注意,这可能比计算完整结果快得多,因为它确保中间数永远不会大于M.
作为一个额外的转折(如果你只对最不重要的数字感兴趣),你可以使用欧拉定理http://en.wikipedia.org/wiki/Euler%27s_theorem来减小指数的大小。
答案 2 :(得分:0)
如果你有一个给定的自然数u和一个给定的输入m,为了计算u ^ m你可以应用以下算法
q = m;
prod = 1;
current = u;
while q > 0 do
if (q mod 2) = 1 then // detects the 1s in the binary expression of m
prod = current * prod; // picks up the relevant power
q--;
endif
current = current * current; // u^i -> u^(2*i)
q = q div 2
enddo
output = prod;
所以基本上如果你有,让我们说,你^ 23 你将23转换为二进制 - > 10111(基数2) 然后你得到u ^ 23 = u ^ 16 * u ^ 4 * u ^ 2 * u ^ 1(没有u ^ 8,因为从左到右的2位数是0)
如果你认为n是log(m)_10 + 1
,复杂度是O(log(m))或O(n)