剑指offer-面试题11-数值的整数次方

1 累乘的方法

package case11_Power;

/**
 * 题目:实现函数 double Power(double base,int exponent),求base的exponent次方。
 * 不得使用库函数,同时不需要考虑大数问题。
 * 
 * 该实现方法计算速度比较慢,需要一次一次的累乘。
 * 
 * @author WangSai
 *
 */
public class Power {

	// 1,考虑exponent为负数,0,正数的情况
	// 2,考虑base为0,e为负数的情况
	// 3,判断双精度数为0,不能用"==",考虑其小于某一个0.000001即为0.0
	/**
	 * 
	 * @param base
	 *            基数
	 * @param exponent
	 *            指数
	 * @return 基数的指数次幂
	 */
	public double PowerBaseExponent(double base, int exponent) {
		// 0的负数次幂
		if (isEqual(base, 0.0) && exponent < 0)
			throw new IllegalArgumentException("非法的输入参数,请重新检查...");
		// 任意数的0次幂
		if (exponent == 0)
			return 1.0;
		// 若指数为负数,则转换为绝对值之后,按照正指数进行计算,然后1/result
		if (exponent < 0) {
			int absExponent = -exponent;
			return 1 / powerWithUnsignedE(base, absExponent);
		}
		return powerWithUnsignedE(base, exponent);

	}

	// 计算指数为正整数的情况
	private double powerWithUnsignedE(double base, int absExponent) {
		double result = 1.0;
		for (int i = 1; i <= absExponent; i++)
			result *= base;

		return result;
	}

	// 在判断底数base是不是等于0时,不能直接写base==0, 这是因为在计算机内表示小数时(包括float和double型小数)都有误差。
	private boolean isEqual(double a, double b) {
		if ((a - b < 0.0000001) && (a - b > -0.0000001))
			return true;
		else
			return false;
	}

	public static void main(String[] args) {
		Power p = new Power();
		double base = 1.0;
		int exponent = 0;
		System.out.println(base + "^" + exponent + ":  " + p.PowerBaseExponent(base, exponent));
		double base1 = 5.0;
		int exponent1 = 2;
		System.out.println(base1 + "^" + exponent1 + ":  " + p.PowerBaseExponent(base1, exponent1));

		double base3 = 5.0;
		int exponent3 = -2;
		System.out.println(base3 + "^" + exponent3 + ":  " + p.PowerBaseExponent(base3, exponent3));

		double base4 = -2.0;
		int exponent4 = -2;
		System.out.println(base4 + "^" + exponent4 + ":  " + p.PowerBaseExponent(base4, exponent4));

		double base5 = 0.0;
		int exponent5 = -2;
		System.out.println(base5 + "^" + exponent5 + ":  " + p.PowerBaseExponent(base5, exponent5));
	}
}


2 递归的方法

package case11_Power;

/**
 * 题目:实现函数 double Power(double base,int exponent),求base的exponent次方。
 * 不得使用库函数,同时不需要考虑大数问题。
 * 
 * 该实现方法通过递归的方式完成。
 * 
 * //a^n=|—— = a^(n/2)*a^(n/2) .............................................. //
 * //....|—— = a^((n-1)/2)*a^((n-1)/2)*a....................................
 * 
 * @author WangSai
 *
 */
public class PowerOp {

	// 通过递归的方式完成
	public double Power3(double base, int exponent) {
		if (isEqual(base, 0.0) && exponent < 0)
			throw new IllegalArgumentException("非法输入参数,请重新检查...");
		// 任意数值的0次幂都是1
		if (exponent == 0)
			return 1.0;
		// 当指数exponent为负数时,先计算以exponent绝对值为幂的值,然后取倒数。
		if (exponent < 0) {
			return 1 / powerByRe(base, -exponent);
		}
		// 当指数exponent为正数
		else {
			return powerByRe(base, exponent);
		}

	}

	// 采用递归的方式完成exponent次幂的计算。
	private double powerByRe(double base, int exponent) {
		if (exponent == 0)
			return 1;
		if (exponent == 1)
			return base;
		double result = powerByRe(base, exponent >> 1);
		result *= result;
		// 如果指数n为奇数,则要再乘一次底数base
		if ((exponent & 1) == 1)
			result *= base;
		return result;
	}

	// 在判断底数base是不是等于0时,不能直接写base==0, 这是因为在计算机内表示小数时(包括float和double型小数)都有误差。
	private boolean isEqual(double num1, double num2) {
		if (num1 - num2 > -0.000001 && num1 - num2 < 0.000001)
			return true;
		else
			return false;
	}

	public static void main(String[] args) {
		PowerOp p = new PowerOp();
		double base = 1.0;
		int exponent = 0;
		System.out.println(base + "^" + exponent + ":  " + p.Power3(base, exponent));
		double base1 = 5.0;
		int exponent1 = 2;
		System.out.println(base1 + "^" + exponent1 + ":  " + p.Power3(base1, exponent1));

		double base3 = 5.0;
		int exponent3 = -2;
		System.out.println(base3 + "^" + exponent3 + ":  " + p.Power3(base3, exponent3));

		double base4 = -2.0;
		int exponent4 = -2;
		System.out.println(base4 + "^" + exponent4 + ":  " + p.Power3(base4, exponent4));

		double base5 = 0.0;
		int exponent5 = -2;
		System.out.println(base5 + "^" + exponent5 + ":  " + p.Power3(base5, exponent5));
	}
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值