剑指OFFER笔记_16_数值的整数次方_JAVA实现

题目:数值的整数次方

  • 实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。

解题思路

  • 此题让我们自己去实现一个库函数,常规状态下的输入是很简单的,关键的地方在于处理好各种特殊情况。
    1. 底数为0。这种情况是没有数学意义的,可以自行设置返回值,只要能够提出此处情况是无意义的就行。
    2. 指数为0。这种情况下底数为任何值都是1。
    3. 指数为负数。这种情况下,需要先将指数转换为正数,然后进行常规的操作,最后对结果取倒数。
  • 出于效率考虑,我们可以将2^16这种问题转换为(2^8)^2,这样就可以减少很多次运算。
  • 此外除法的效率远低于移位操作,可以用>>右移操作来代替除以2。此时对应的对2取余操作也用位与运算来代替(n & 1)。
  • 在LeetCode上做题时遇到了一个很头痛的问题,就是如果输入的指数为-2^31时,我代码中将指数转换为正数时失败了。经过思考,我找到了原因,计算机在存储-2^31时是以补码的形式存储的,如果取其相反数,也就是将补码再次求补码,得到的还是补码本身,这就会让这个程序无法结束,解决方案是在函数中用long类型代替int来存储指数,以便求相反数。

代码

函数主体部分代码

package q16;

/**
 * 数值的整数次方。
 * 实现函数double Power(double base, int exponent),求base的exponent次方。
 * 不得使用库函数,同时不需要考虑大数问题。
 */
public class Solution {
    public double myPow(double x, int n) {
        //任何数的0次方都是1。
        //0的任何次方都没有数学意义。
        if(((x-0.0 < 1e-9)&(x-0.0 > -1e-9) ) || n == 0)
        {
            return 1;
        }
        if ((x-1.0 < 1e-9)&(x-1.0 > -1e-9) || n == 1)
        {
            return x;
        }

        int flagOfNegative = 0;
        //此处如果用int,在某些特殊情况会出错
        long absN = n;
        double result;
        //当n<0时,先计算绝对值次方,再取倒数。
        if (n < 0)
        {
            flagOfNegative = 1;
            absN = -absN;
        }
        result = PowerOfPositive(x, absN);

        if (flagOfNegative == 1)
        {
            result = 1.0/result;
        }
        return result;
    }

    public double PowerOfPositive(double x, long absN)
    {
        if(absN == 0)
        {
            return 1.0;
        }
        if (absN == 1)
        {
            return x;
        }
        //提高效率
        double result = PowerOfPositive(x, absN>>1);

        result = result * result;
        //若absN为奇数,需要再乘一个x
        if ((absN & 1) == 1)
        {
            result *= x;
        }
        return result;
    }
}

测试部分代码

package q16;

public class TestApp {
    public static void main(String[] args) {
        Solution solution = new Solution();
        System.out.println("0的4次方是: " + solution.myPow(0, 4));
        System.out.println("1的4次方是: " + solution.myPow(1, 4));
        System.out.println("2的4次方是: " + solution.myPow(2, 4));
        System.out.println("2的6次方是: " + solution.myPow(2, 6));
        System.out.println("2的-2147483648次方是: " + solution.myPow(2, -2147483648));
    }
}

运行结果截图

在这里插入图片描述

LeetCode运行截图

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值