求一个数的整数次方

/**
 * 求一个数的整数次方
 */
public class PowerOperator {

    /**
     * 问题:求一个数的整数次方
     *
     * @param base      基数
     * @param exponent  指数
     */
    public static double power(double base, int exponent) {

        double precision = 0.000001;
        if (equals(base,0.0,precision) && exponent <= 0) {
            return 0.0;
        }

        int positiveExponent = exponent < 0 ? -exponent : exponent;

//        double result = powerWithPositiveExponent(base, positiveExponent);
        double result = powerWithPositiveExponent2(base, positiveExponent);

        if (exponent < 0) {
            result = 1.0/result;
        }

        return result;
    }


    /**
     * 获取base的positiveExponent次方
     *
     * @param base  基数
     * @param positiveExponent  正指数
     * @return
     */
    public static double powerWithPositiveExponent(double base, int positiveExponent) {

        double result = 1.0;
        for (int i = 1; i <= positiveExponent; i++) {
            result = result * base;
        }
        return result;
    }


    /**
     * 思想:
     *      1)将运算过程 分解为 多个相同的子运算+其它运算
     *      2)相同的子运算只需要计算一次即可,当再次遇到同样的子运算时,复用第一次计算的结果,这样可以大大的提高计算的速度。
     *
     * 公式:
     *       { a^(n/2) * a^(n/2)                n为偶数
     *  a^n =|
     *       { a^((n-1)/2) * a^((n-1)/2) * a    n为奇数
     *
     *  注:n为奇数时,n-1为偶数 ==> a^n = a^(n-1) * a = (a^((n-1)/2) * a^((n-1)/2)) * a
     *
     * @param base  基数
     * @param positiveExponent  正指数
     * @return
     */
    public static double powerWithPositiveExponent2(double base, int positiveExponent) {

        if (positiveExponent == 0) return 1;
        if (positiveExponent == 1) return base;

        double result;

        if ((positiveExponent & 1) == 1) { // positiveExponent为奇数
            double temp = powerWithPositiveExponent2(base, (positiveExponent-1) >> 2);
            result = temp * temp * base;
        } else {
            double temp = powerWithPositiveExponent2(base, positiveExponent >> 2);
            result = temp * temp;
        }

        return result;
    }


    /**
     * 计算机在表示小数(float/double)时会有一定的误差。
     *
     * 当二者之差的绝对值小于精度时,我们认为这两个数相等。
     *
     * @param num1
     * @param num2
     * @param precision 精度
     * @return
     */
    public static boolean equals(double num1, double num2, double precision) {

        if (-precision <= num1 - num2 && num1 - num2 <= precision) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) {

        double result = power(2, 4);
        double result2 = power(2, -4);
        System.out.println(result);
        System.out.println(result2);

    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值