劍指Offer面試題:10.數值的整數次方


一、題目:數值的整數次方

題目:實現函數double Power(doublebase, int exponent),求base的exponent次方。不得使用庫函數,同時不需要考慮大數問題。

  在.NET Framework提供的BCL中,Math類實現了一個Pow方法,例如要求2的三次方,可以通過以下代碼實現:

    double result = Math.Pow(2, 3);

  本題就是要實現一個類似於該Pow方法的功能。

二、解決思路與實現

2.1 不加思索的思路

  不需要考慮大數問題,可以在30秒內想到的思路如下:

    public double Power(double baseNumber,int exponent)
    {
        double result = 1;
        for (int i = 1; i <= exponent; i++)
        {
            result = result * baseNumber;
        }

        return result;
    }

  但是,上面的代碼沒有考慮到輸入的指數(exponent)小於1即是零和負數的時候怎么辦,它只考慮了指數是正數的情況。

2.2 全面考慮的思路

  (1)當指數為負數的時候:可以先對指數求絕對值,然后算出次方的結果之后再取倒數

  (2)當底數(base)是零且指數是負數的時候:通過全局代碼或異常告訴調用者參數有誤

  (3)0的0次方的時候:由於0的0次方在數學上是沒有意義的,因此無論是輸出0還是1都是可以接受的。

    public static bool isInvalidInput = false;

    public static double Power(double baseNumber, int exponent)
    {
        isInvalidInput = false;

        // 當底數(base)是零且指數是負數的時候提示參數非法
        if (Equals(baseNumber, 0.0) && exponent < 0)
        {
            isInvalidInput = true;
            return 0.0;
        }

        uint absExponent = (uint)exponent;
        if (exponent < 0)
        {
            absExponent = (uint)(-1 * exponent);
        }

        double result = PowerWithUintExponent(baseNumber, absExponent);

        // 當指數為負數的時候需算出次方的結果之后再取倒數
        if(exponent < 0)
        {
            result = 1.0 / result;
        }

        return result;
    }

    private static double PowerWithUintExponent(double baseNumber, uint exponent)
    {
        double result = 1.0;
        for (int i = 1; i <= exponent; i++)
        {
            result = result * baseNumber;
        }

        return result;
    }

    /// <summary>
    /// 在判斷底數base是不是等於0時,不能直接寫base==0,
    /// 這是因為在計算機內表示小數時(包括float和double型小數)都有誤差。
    /// </summary>
    private static bool Equal(double num1, double num2)
    {
        if (num1 - num2 > -0.0000001 &&
            num1 - num2 < 0.0000001)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

細節:在判斷底數baseNumber是不是等於0時,不能直接寫baseNumber==0,這是因為在計算機內表示小數時(包括float和double型小數)都有誤差。判斷兩個小數是否相等,只能判斷它們之差的絕對值是不是在一個很小的范圍內。如果兩個數相差很小,就可以認為它們相等。

三、單元測試

3.1 測試用例

    // 底數、指數都為正數
    [TestMethod]
    public void PowerTest1()
    {
        Assert.AreEqual(PowerHelper.Power(2, 3), 8);
    }

    // 底數為負數、指數為正數
    [TestMethod]
    public void PowerTest2()
    {
        Assert.AreEqual(PowerHelper.Power(-2, 3), -8);
    }

    // 指數為負數
    [TestMethod]
    public void PowerTest3()
    {
        Assert.AreEqual(PowerHelper.Power(2, -3), 0.125);
    }

    // 指數為0
    [TestMethod]
    public void PowerTest4()
    {
        Assert.AreEqual(PowerHelper.Power(2, 0), 1);
    }

    // 底數、指數都為0
    [TestMethod]
    public void PowerTest5()
    {
        Assert.AreEqual(PowerHelper.Power(0, 0), 1);
    }

    // 底數為0、指數為正數
    [TestMethod]
    public void PowerTest6()
    {
        Assert.AreEqual(PowerHelper.Power(0, 4), 0);
    }

    // 底數為0、指數為負數
    [TestMethod]
    public void PowerTest7()
    {
        Assert.AreEqual(PowerHelper.Power(0, -4), 0);
        Assert.AreEqual(PowerHelper.isInvalidInput, true);
    }

3.2 測試結果

  (1)測試通過結果

  (2)代碼覆蓋率結果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM