自語之快速冪的使用
前言
昨天晚上,筆者下班後閒著沒事,就開始了網上刷題之旅。
期間,恰好遇見了一道關於快速冪的問題。其實,在大學學習演演算法的時候,就曾瞭解過該演演算法。不過,當時碼題的時候死活想不起來。
看來,筆者的題還沒刷夠!
快速冪能解決什麼問題?
在重溫快速冪的過程中,筆者搜尋了很多博文,大部分的內容除了理論還是理論。其實,很多時候像這種不常用的小演演算法,我們只想知道該演演算法能解決什麼問題,不想知道其底層原理和理論。
話不多說,我們看看這題:
給定一個double型別的浮點數base和int型別的整數exponent。求base的exponent次方。
複製程式碼
這道題除了用迴圈疊乘和二分疊乘的方法外,快速冪在這種場景極其適用,即求一個數的N次冪。
那..如何使用快速冪?
這一部分內容,筆者不講快速冪的內容,只講快速冪的使用和如何用程式碼實現。
我們來看個例子:計算3^5
(3的5次方)
上述例子可以拆解為:底數=3
,指數=5
。快速冪的要點是,利用指數的二進位制的位數進行疊乘運算。
什麼?利用指數的二進位制的位數進行疊乘運算!!!
沒錯,我們來看看,指數5的二進位制形式為:0101
。這裡筆者是利用8421碼算出其指數的二進位制的….
得到指數的二進位制碼後,我們從右向左看,每前進一個位數,底數就要翻倍(疊乘),如圖1-1。
從上圖,我們很容易得到:3 ^ 5 = 3 ^ 4 * 3 ^ 1
得到二進位制碼後,可以利用指數5和1的二進位制數,加上移位操作來判斷當前二進位制的末尾
如果為1,則說明當前二進位制數是疊乘結果的組成部分之一。
從上文的8421碼的表示式中:3 ^ 5 = 3 ^ 4 * 3 ^ 1
可以得到:3 ^ 5
的疊乘結果由3 ^ 4
和 3 ^ 1
組成。
我們可以很快的寫出程式碼,核心程式碼主要是計算3 ^ 4 和3 ^ 1
的結果,如下:
// result = 疊乘結果
// base = 底數
// exponent = 指數
double result = 1,cur = base;
while (exponent != 0) {
if ((exponent & 1) == 1) { // 計算疊乘結果
result *= cur;
}
cur *= cur; // 翻倍(1-1)
exponent >>= 1; // 指數右移一位
}
複製程式碼
程式碼中,翻倍(1-1)操作是根據指數的二進位制碼中,底數就要翻倍的原理。
而且,在翻倍操作中,不管末尾&操作(圖1-2)的結果是否為1,都需要進行翻倍操作!
總結
寫到這裡,關於快速冪演演算法,筆者也不知道讀者們理解沒有….
如果無法理解,也沒關係。
畢竟,快速冪演演算法除了在碼題的時候可能會遇到以外,其他時候有可能一輩子也用不到。