【剑指offer-Java版】11数值的整数次方

来源:互联网 发布:淘宝手机端首页gif 编辑:程序博客网 时间:2024/06/09 04:34

不用库,实现pow()运算
很简单的题目,但是涉及到很多细节

比如
1) 结果非法或者出错的时候如何通知调用者:
可以采用返回特定值的方法-但是此处pow运算既可以返回正数 0 或者负数,所以此思路比较麻烦
可以采用全局变量加上返回值的方法-缺点是比较容易忘记检查全局变量的标志
可以直接使用异常机制来实现-就是此处的方法了,虽然异常的缺点在于可能会导致程序执行流程的极大改变,但是比较方便

2) 输入的组合情况
base为正 exp为正 - 直接算
base为负 exp为正 - 直接计算
base为0 exp为正 直接返回0

base为正 exp为0 - 直接返回1
base为负 exp为0 - 直接返回1
base为0 exp为0 - 无意义,返回1

base为正 exp为负 - 正常计算后求倒
base为负 exp为负 - 正常计算求倒
base为0 exp为负 - 非法运算抛出异常

3) 其他的一些优化以及注意的细节
pow运算针对的都是浮点运算,所以精度有要求-浮点数大小对比需要不是和0而是和0.00…..0001
一些计算加速技巧-需要积累

    public class _Q11 {    public double Pow(double base, int exp) throws Exception{        if(equals(base, 0.0) && (exp < 0)) { throw new Exception("invalid input, check the base");}        if(equals(base, 0)) return 0;        if(exp == 0) return 1;        if(exp == 1) return base;        if(exp < 0) return 1.0/PowWithUnsignedExpR(base, -exp);        return PowWithUnsignedExp(base, exp);    }    /**     * 这个地方看到书上是用的递归,代码挺巧妙的就是不易读 - 需要结合那个公式     */    public double PowWithUnsignedExp(double base, int exp){        double result = base;        int count = 1;        if((exp & 0x01) == 0){ // 指数为偶数            while(count < exp){                result = result*result;                count = (count<<1);            }        }else{ // 指数为奇数            while(count < (exp - 1)){                result = result*result;                count = (count<<1);            }            result = result * base;        }        return result;    }    public double PowWithUnsignedExpR(double base, int exp){        // 出口        if(exp <= 1) return exp*base;        double result = PowWithUnsignedExpR(base, exp>>1);        result *= result;        if((exp & 0x01) == 1) result *= base;         return result;    }    public boolean equals(double num1, double num2){        boolean result = false;        if((num1 - num2 < 0.00001) && (num1 - num2 > -0.00001)) result = true;        return result;    }    }

测试代码:

    public class _Q11Test extends TestCase {    _Q11 pow = new _Q11();    public void testMinInReverse() throws Exception{        double base1 = 0.0;        int exp1 = 2;        double base2 = 0.0;        int exp2 = -2;        double base3 = 5;        int exp3 = 1;        double base4 = 5;        int exp4 = -2;        double base5 = 5;        int exp5 = 0;        double base6 = 5;        int exp6 = 2;        System.out.println(pow.Pow(base1, exp1));        try {            System.out.println(pow.Pow(base2, exp2));        } catch (Exception e) {            e.printStackTrace();        }        System.out.println(pow.Pow(base3, exp3));        System.out.println(pow.Pow(base4, exp4));        System.out.println(pow.Pow(base5, exp5));        System.out.println(pow.Pow(base6, exp6));    }    }
1 0
原创粉丝点击