【问题标题】:What's the fastest algorithm to perform exponentiation?执行求幂的最快算法是什么?
【发布时间】:2012-02-24 16:18:05
【问题描述】:
执行求幂的最快算法是什么?为简单起见,我们假设自然数基数和指数。
高效的数学库会使用什么?
(当我搜索它时,我只会得到与在指数时间内运行的算法有关的结果。)
【问题讨论】:
-
-
-
-
Knuth 在这个问题中投入了几页 TAOCP 第 2 卷。
标签:
algorithm
math
language-agnostic
【解决方案1】:
上述所有二进制方法的问题在于它们仅限于整数。如果“取幂”是指计算 e^x 函数,那么我所见过的最好的方法是快速收敛的幂级数,以及在有限范围内有效的多项式、有理或 Pade 近似。
有一件事是肯定的:如果您找到了一种将 e^x 精确到小数点后 96 位的快速算法,那么您还将找到一种更快的计算日志的方法(Newton-Raphson)。事实上,Newton-Raphson 是二次收敛的,因此每次迭代都会使日志中的精度位数加倍。这是 UCLA 的 Nate Grossman 在 Forth 时代的最爱。
在四键计算器时代,我曾经使用 e^x = (1+x/1024)^10。当然,对于非常大或非常小的 x 来说,这会失效,但是您可以看到它为什么起作用。如果你有一个平方根按钮,你可以颠倒这个想法来获得对数。但是指数函数不需要平方根。
我想知道是否有一些 AGM 算法的反演可以做指数函数...嗯....
【解决方案3】:
如果你有给定的自然数 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;
所以基本上如果你有,比如说,u^23
您将 23 转换为二进制 -> 10111(base 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)