如果您打算使用大數字而不是重新發明輪子,那麼您可能應該查看GNU MP Bignum Library。
關於遞歸與迭代的問題,答案是你總是可以把它們寫成等價的;一個只能自稱爲tail call的遞歸函數與while循環一樣高效(前提是您的編譯器支持尾部調用優化,但最常用的編譯器是)。舉例來說,你所描述的快速冪函數的尾遞歸版本(僞代碼):
function fastExp(base, exponent, accumulator) {
if(exponent == 0) {
return accumulator;
} else if(exponent % 2 == 0) {
return fastExp(base * base, exponent/2, accumulator);
} else {
return fastExp(base, exponent-1, base * accumulator);
}
}
覺得這個遞歸函數爲一個循環,在循環條件是exponent != 0
的,和遞歸呼叫類似於goto
s到循環的開始。 (您需要accumulator = 1
調用它,當你開始,順便說一句。)這是等同於以下:
function fastExp(base, exponent) {
var accumulator = 1;
while(exponent != 0) {
if(exponent % 2 == 0) {
base *= base;
exponent /= 2;
} else {
exponent -= 1;
accumulator *= base;
}
}
return accumulator;
}
所以你可以看到,他們是等價的,因此,將執行相同數量的操作。
您是否嘗試過移位?或者你是否需要十進制這個非常大的數字? – Mysticial 2012-01-17 05:56:38
我只使用自然數,但他們需要精確到2^100000這麼大的數字,目前我的程序需要13秒才能完成,因爲如果指數是2的乘方因爲迭代過程很簡單,高效的算法達到一個點,然後開始乘以2增加所花費的時間。 – emschorsch 2012-01-17 06:01:10
相關:http://stackoverflow.com/questions/8771713/efficient-exponentiation-for-huge-numbers-im-talking-googols如果你想在十進制而不是二進制答案。那麼更多的是如何從二進制轉換爲十進制的問題。 – Mysticial 2012-01-17 06:08:21