题目描述
实现函数double power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
测试用例
把 底数 和 指数 分别设为正数、负数和零。
题目考点
- 考察应聘者 思维的全面性。
- 对效率比较高的面试官还会考察应聘者快速做乘方的能力。
解题思路
全面但不够高效的解法
考虑exponent为负数
当指数为负数的时候,我们可以先对指数取绝对值,算出次方的结果之后再取倒数。在想到取倒数的时候,我们又要想到对0取倒数的问题,这就要我们进行错误处理,处理的方式主要有三种:返回值、全局变量和异常。面试的时候可以阐述每种方法的优缺点,然后一起讨论决定选用哪种方法。
值得注意的是,由于0的0次方在数学上是没有意义,因此无论输出是0还是1都可以接受,但这都需要和面试官说清楚,表明我们已经考虑到这个边界值了。
既全面又高效的解法
这是对上面解法的补充,主要利用了下面的公式:
a^n = a^(n/2) * a^(n/2) ; n为偶数
a^n = a^((n-1)/2) * a^((n-1)/2) * a ; n为基数
package Sword;
/**
* 实现函数double power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
* 考虑异常处理、边界条件
* @author tyler
*
*/
public class Power {
public static void main(String[] args) {
System.out.println(Power1(2, -2));
}
// -----------全面高效-----------------------------------
public static double Power1(double base, int exponent) {
// 异常处理
boolean g_InvalidInput = false; // 标识是否有异常
if (base == 0.0 && exponent < 0) {
g_InvalidInput = true;
return 0.0; // 0的几次方没意义,结果为0或者1
}
// 考虑指数正负
int absExponent = exponent;
if (exponent < 0) {
absExponent = (-1)*exponent;
}
double result = PowerWithUnsignedExponent(base, absExponent); // 调用功能模块
if (exponent < 0) {
result = 1.0/result;
}
return result;
}
// 功能模块:
public static double PowerWithUnsignedExponent(double base, int exponent) {
if (exponent == 0) {
return 1;
}
if (exponent == 1) {
return base;
}
double result = PowerWithUnsignedExponent(base, exponent>>1);
result *= result;
// 与1按位与为1的为奇数
if ((exponent & 0x1) == 1) {
result *= base;
}
return result;
}
}