[剑指Offer]数值的整数次幂

剑指Offer——数值的整数次幂

题目描述

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

保证base和exponent不同时为0。

解法一:直接法

注意的问题:

1、 关于次幂的问题特殊的情况,比如次幂为负数,或者基数为0时等等复杂的情况。(由于指数是int 类型,所以要区分整数还是负数或者0.)

2 、机器中浮点数的比较是由误差的,因此double类型的比较,不能用简单的a==0来比较。一般的比较方式是,相减的差在一个很小的区间内,我们就认为是相等的。
  
直接方法:直接连续累乘。

public class Solution {
   public double Power(double base, int exponent) {
		 double mul=1.0;
		 /* 如果exponent = 0 输出1 */
	        if(exponent == 0)
	        {
	            return 1.00000;
	        }
 
	        /* 如果base = 0 输出0 */
	        if(base >= -0.000001 && base <= 0.000001)
	        {
	            return 0;
	        }
	        /* 如果指数大于0 */
	        if(exponent > 0)
	        {
	            for(int index = 0; index < exponent; index++)
	            {
	                mul *= base;
	            }
	        }
	        else
	        {
	            exponent = -exponent;
	            for(int index = 0; index < exponent; index++)
	            {
	                mul *= base;
	            }
	            mul = 1.0/mul;
	        }
	        return mul;
	  }
}

解法二:快速幂运算

分析:直接累乘的方法固然很简单,但是往往会造成多次相乘运算,这样反而不好。
将指数用二进制数表达,例如:13表达为二进制1101。 通过&1和>>1来逐位读取1101,为1时将该位代表的乘数累乘到最终结果
举例:10^1101 = 10^0001 * 10^0100 * 10^1000。
在这里插入图片描述
仔细观看上面公式发现:

我们可以通过在循环里通过自乘运算依次实现,而 这些指数前面的系数=指数对应的每一位二进制数。exponent = 11 = 1011(二进制)。

所以,我们可以这样实现这个快速幂运算。

  • step1:首先需要知道在每次循环里通过自乘计算base的2的指数次方。循环的次数就是所求指数exponent的二进制位数

  • step2: 其次就是对于每个base的2的指数次方,乘以其相对应的二进制位上的数。

  • step3: 循环里不断的累成step2里计算的结果。

public class Solution {
    public double Power(double base, int exponent) {
        double result = 1.0,currentResult = base;
        int n = 0;
        if(exponent > 0) {
            n = exponent;
        } else if(exponent < 0) {
            if(base == 0){
                new RuntimeException("分母不能为0");
            }
            n = - exponent;
        }else if(exponent == 0) {
            //0的0次幂
            return 1.0;
        }
        while(n != 0) {
            if((n & 1) == 1){
                result *= currentResult;
            }
            //当前结果翻倍(因为上面公式的每一个项base^2会加倍)
            currentResult *= currentResult;
            //将exponent指数的二进制形式右移一位,继续循环,取出二进制的最低位
            n = n >> 1;
        }
        if(exponent >= 0) {
            return result;
        }else {
            return (1/result);
        }
    }
}

递归解决:

double Power(double base, int exponent) {
        //指数为0时,结果为1
        if(exponent == 0) 
            return 1;
        //底数为0时,结果为0
        if(base == 0) 
            return 0;
        //指数为1时,结果为base
        if(exponent == 1)
            return base;
        //指数为-1时,结果为1/base
        else if(exponent == -1)
            return 1/base;
        //其它情况(分解幂计算)
        return Power(base,exponent/2) * Power(base,exponent/2) * Power(base,exponent%2);
    }
发布了115 篇原创文章 · 获赞 22 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_42956047/article/details/105309428