The sword refers to the offer - the integer power of the value

Topic description

  • Given a float base of type double and an integer exponent of type int. Find the exponent power of base.
  • Address: Niu Ke Link

Solution

  • This is a very classic bit operation problem
  • First, this is a question with a lot of special cases:
    • When the index is 0, return 1 directly
    • The base is 0, but when the exponent is negative, a division by 0 exception occurs, and when the exponent is positive, 0 is returned;
    • Other cases (use the following three methods)
  • Method 1: After judging the boundary conditions, loop directly. If the absolute value of the index is n, then the time complexity of this method is O(n)
  • Method 2: Use the idea of ​​fast power , for example, to find 3^11, then the binary of index 11 is 1011. For 1011, from right to left, each bit corresponds to 1, 2, 4, 8. And 3^11 = 3^(1011) = 3^(1000 + 0010 + 0001) = 3^8 * 3^2 + 3^1 . So we can look at it this way, 1011 corresponds to 3, 3^2, 3^4, 3^8 from right to left , which is a doubling relationship. Therefore, as long as we get each digit
    of the binary bit by bit of the exponent , see whether the current bit is 1 or 0. If it is 1, it will be multiplied into res, and doubled in each bit-by-bit process , 3, 3^ 2, 3^4, 3^8. So how do you get each digit of the binary bit by bit? Using left shift >> and &, &1 can get the value of the lowest digit, and then the current number >> can get the number on the next digit until it becomes 0.

    Time Complexity: O(log N)

  • Method 3: Recursion . 3^11 = 3^5 * 3^5 3 3^10 = 3^5 3^5. So first judge the parity of the exponent

    • If odd: f(base, exp) = f(base, exp > >1) * f(base, exp > >1) * base
    • If even: f(base, exp) = f(base, exp > >1) * f(base, exp >> 1)

    Time complexity: O(log N)

lessons learned

  • Use of fast powers
  • How to use >> and &1 to get each bit of a number in binary form
  • Any number greater than or equal to 1 can be obtained by adding 1, 2, 4, 8, 16, 32... The last digit in binary must be 1. So you can use n & 1 != 0 to judge the parity of n. Note that when using n % 2 != 0 to judge parity, it must be followed by != 0, not! = 1, because for negative numbers, such as -1, the remainder is -1, but it is still an odd number.
  • n >> 1 achieves the effect of dividing by 2, of course, this is for positive numbers, and negative numbers will be shifted to the right with a sign
  • Calculate 2^n, that is, 1 << n, and others can be solved by fast power.
  • The code must be read often, this is a very classic topic of bit operation

Code:

  • Method 2:
    public double Power(double base, int exponent) {
        //指数为0
        if (exponent == 0) {
            return 1.0;
        }
        if (base - 0.0 == 0.00001 || base - 0.0 == -0.00001)  {
            //底为0,指数为负数
            if (exponent < 0) {
                throw new RuntimeException("除0异常"); 
            }else{ //底为0,指数为正数
                return 0.0;
            }
        }
        //先按正指数算
        int e = exponent > 0 ? exponent: -exponent;
        double res = 1;
        //快速幂
        while (e != 0) {
            //根据当前位是1还是0决定累乘还是不累乘
            res = (e & 1) != 0 ? res * base : res;
            //翻倍
            base *= base;
            //右移,迭代
            e = e >> 1;
        }
        //根据指数正负,返回
        return exponent > 0 ? res : 1/res;
  }
  • Method 3:
    public double Power(double base, int exponent) {
        if (exponent == 0) {
            return 1.0;
        }
        if (base - 0.0 == 0.00001 || base - 0.0 == -0.00001 )  {
            if (exponent < 0) {
                throw new RuntimeException("除0异常"); 
            }else{
                return 0.0;
            }
        }
        return exponent > 0 ? getPower(base, exponent) : 1/getPower(base, -exponent);
    }

    //传入的e肯定是正数
    public static double getPower(double base, int e) {
        //base case
        if (e == 1) {
            return base;
        }
        //递归计算 f(base,e >> 1)
        double halfPower = getPower(base, e >> 1);
        //根据指数的奇偶计算 f(base,e)
        return (e & 1) != 0 ? base * halfPower * halfPower : halfPower * halfPower;
    }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324140850&siteId=291194637