數值的整數次方

題目描述

給定一個double類型的浮點數base和int類型的整數exponent。求base的exponent次方。保證base和exponent不同時爲0

解題思路

本題描述的是求數值的次方,該題描述也正是JDK中Math.pow(a,b)方法
這裏給出倆個解法:
第一個解法是:使用循環不停的迭代乘積,然後返回累計的結果.注意對於指數爲負數的情況考慮

  public double Power(double base, int exponent) {
        double result = 1d;
        int symbol = exponent > 0 ? exponent : -exponent;
        for (int i = 0; i < symbol; i++) {
            result *= base;
        }
        return exponent > 0 ? result : 1 / result;
    }

第二種解法使用的是快速冪的方式,該方式通過位運算,因此它的效率也是最好的,其時間複雜度爲 O(log₂N), 與樸素的O(N)相比效率有了極大的提高
首先我們來認識一下快速冪:快速冪指的是快速算底數的n次冪,這裏給出百科中計算實例
在這裏插入圖片描述
對於上面的原理實例我們逐個拆解分析:
1:對於本題我們肯定要把指數換算成二進制數,比如11,換算成1011
2:經過換算之後,然後在對比原理實例中最後一行公式,我們可以看到如果二進制位爲0,那麼將不需要累積結果,因此在代碼中我們需要逐位判斷當前位是否爲0,如果爲0,那麼該結果不需要累積,否則累積結果.對應着代碼的 if((symbol & 1) == 1) res *= curr;功能實現
3: 公式是計算整體結果的,但是應該把這個補全,就是在中間缺少a22次方,只不過2的11次方對應位置爲0,但是如果先拼接上在看的話,每個位置上的值都是上一個計算結果的翻倍,(a2)2,(a2)3這樣看的話清楚 curr *= curr;代碼的含義了.它就是根據截圖中的公式進行計算的,不管二進制是否爲0,每次都會翻倍,而是否取當前值作爲累積乘積看的就是上面的 if ((symbol & 1) == 1)判斷了.
4:現在整體看下while部分的解釋,首先不能爲0,如果爲0那麼直接返回res=1,
然後每次拿指數二進制數和1做與運算,即判斷最右一位是否爲1,如果是累積乘積當前結果,並且將乘積值翻倍,如果最右一位是否爲0,那麼不進行累積,且也需要將乘積翻倍,然後都執行右移操作,即判斷左邊一位,直至二進制位全部取完,即二進制數爲1,退出運算,返回結果.

public double Power(double base, int exponent) {
        double res = 1, curr = base;
        int symbol = exponent > 0 ? exponent : -exponent;
        while (symbol != 0) {
            if ((symbol & 1) == 1)
                res *= curr;
            // 不管當前位是否爲0都需要進行翻倍
            curr *= curr;
            // 右移一位
            symbol >>= 1;
        }
        return exponent >= 0 ? res : (1 / res);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章