题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
思路:
base:+ - 0;exponent : + - 0;
base的正负号影响并不大,倒是等于0会产生较大的影响,就是对0exponent的讨论。产生的问题是0负数,是一个错误的输入。
假设base不为0,接下来就是对exponent的分别讨论了。
- 1。 最终结果也是1.
- 正数。 直接乘,得出结果。例如 25,就是2 * 2 * 2 * 2 * 2;
- 负数。 先转换成正数的运算,最后再让 1 除以正数的结果,就得到我们需要的结果。
代码如下:
class Solution {
public:
double Power(double base, int exponent) {
int n;
bool minus = false;
long double result, temp;//考虑大数,有可能会产生溢出,所以这里使用 long double
//如果 base 是0的话,就会产生问题
if (exponent == 0){
return 1;
} else if (exponent > 0) {
n = exponent;
} else {
n = -exponent;
minus = true;
}
result = 1;//使用之前记得进行初始化
for (int index = 1; index <= n; index++)
{
result *= base;
}
return (minus == false) ? result : 1 / result;
}
};
修改一下,上述代码运算次数比较多,例如28要进行7次乘法运算,可以想办法让乘法运算次数减少。采用指数增长法,每次乘完之后的数字保存起来,以方便进行下一次乘法运算。举例说明:还是28,2 * 2 存储到temp中,幂指数增长,下次执行temp = temp * temp。(到这里想法还不是很成熟)
代码如下:
class Solution {
public:
double Power(double base, int exponent) {
int n, index;
bool minus = false;
long double result, temp;//有可能会产生溢出,所以这里使用 long double
//如果 base 是0的话,就会产生问题
if (exponent == 0){
return 1;
} else if (exponent > 0) {
n = exponent;
} else {
n = -exponent;
minus = true;
}
//考虑一个问题,如果遍历的速度是很慢的,假如是8,要进行7次乘法运算
//那么可以让他增长速度更快一点,采用2的指数递增法,假如是8,要进行3次乘法运算
temp = base;//使用之前记得进行初始化
for (index = 2; index <= n; index = index * 2)
{
temp *= temp;
}
result = temp;
if (index > n)
{
index = index / 2;
}
while (n - index)
{
result *= base;
n--;
}
return (minus == false) ? result : 1 / result;
}
};
再多加考虑产生异常输入的问题。
0负数,返回值0.0,与正常输入会产生相同的结果,为了与正常结果进行区分,使用全局变量记录错误产生。
对于一个整数,在内存中是以二进制进行存储的,例如13(0x1101),213=20x0001*20x0100*20x1000;
最终代码如下:
class Solution {
public:
bool g_InvalidInput = false;
double Power(double base, int exponent) {
//在使用之前应该先对 g_InvalidInput 进行初始化
//否则非常有可能使用的是上次程序执行的那个值
g_InvalidInput = false;
//处理错误的输入问题
if (equal(base, 0.0) && exponent < 0) {
g_InvalidInput = true;
return 0.0;//这里相当于增加了使用该函数的用户的负担,值得商榷
}
unsigned int absExponent = (unsigned int)(exponent);
if (exponent < 0) {
absExponent = (unsigned int)(-exponent);
}
double result = PowerWithAbsExponent(base, absExponent);
if (exponent < 0) {
return 1.0/result;
} else {
return result;
}
}
private:
double PowerWithAbsExponent(double base, int exponent)
{
if (exponent == 0) {
return 1.0;
} else if (exponent == 1) {
return base;
}
/*
//递归是一直往回倒
double result = PowerWithAbsExponent(base, exponent >> 1);
result *= result;
if ((exponent & 0x1) == 1) {
result *= base;
}
*/
//尝试正向来做
double temp = base;
double result = 1.0;
while (exponent != 0) {
if ((exponent & 0x01) == 1) {
result *= temp;
}
temp *= temp;
exponent >>= 1;
}
return result;
}
//由于浮点数在内存存储中会产生一定的误差, 所以浮点数判断相等只要在一个较小的范围内即可
bool equal(double num1, double num2)
{
if ((num1 - num2 < 0.0000001) && (num1 - num2 > -0.0000001)){
return true;
} else {
return false;
}
}
};