1. 程式人生 > 程式設計 >自語之快速冪的使用

自語之快速冪的使用

前言

昨天晚上,筆者下班後閒著沒事,就開始了網上刷題之旅。

期間,恰好遇見了一道關於快速冪的問題。其實,在大學學習演演算法的時候,就曾瞭解過該演演算法。不過,當時碼題的時候死活想不起來。

看來,筆者的題還沒刷夠!

快速冪能解決什麼問題?

在重溫快速冪的過程中,筆者搜尋了很多博文,大部分的內容除了理論還是理論。其實,很多時候像這種不常用的小演演算法,我們只想知道該演演算法能解決什麼問題,不想知道其底層原理和理論。

話不多說,我們看看這題:

給定一個double型別的浮點數base和int型別的整數exponent。求base的exponent次方。
複製程式碼

這道題除了用迴圈疊乘和二分疊乘的方法外,快速冪在這種場景極其適用,即求一個數的N次冪。

那..如何使用快速冪?

這一部分內容,筆者不講快速冪的內容,只講快速冪的使用和如何用程式碼實現。

我們來看個例子:計算3^5 (3的5次方)

上述例子可以拆解為:底數=3,指數=5。快速冪的要點是,利用指數的二進位制的位數進行疊乘運算。

什麼?利用指數的二進位制的位數進行疊乘運算!!!

沒錯,我們來看看,指數5的二進位制形式為:0101。這裡筆者是利用8421碼算出其指數的二進位制的….

得到指數的二進位制碼後,我們從右向左看,每前進一個位數,底數就要翻倍(疊乘),如圖1-1。

企業微信20190810113152.png

從上圖,我們很容易得到:3 ^ 5 = 3 ^ 4 * 3 ^ 1

得到二進位制碼後,可以利用指數5和1的二進位制數,加上移位操作來判斷當前二進位制的末尾

數是否為1,如圖1-2:

企業微信20190810115216.png

如果為1,則說明當前二進位制數是疊乘結果的組成部分之一。

從上文的8421碼的表示式中:3 ^ 5 = 3 ^ 4 * 3 ^ 1可以得到:3 ^ 5的疊乘結果由3 ^ 43 ^ 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,都需要進行翻倍操作!

總結

寫到這裡,關於快速冪演演算法,筆者也不知道讀者們理解沒有….

如果無法理解,也沒關係。

畢竟,快速冪演演算法除了在碼題的時候可能會遇到以外,其他時候有可能一輩子也用不到。