《剑指Offer》面试题11:数值的整数次方
1 代码的规范性
影响代码规范性的因素:书写、布局和命名。
用完整的英文单词组合命名变量和函数。
2 代码的完整性
1)从3方面确保代码的完整性
2)3种错误处理的方法
3 面试题11:数值的整数次方
知识点
代码的完整性
题目描述
实现函数double Power(double base,int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大树问题。
解题思路及代码(原书)
这道题目有以下几点需要注意:
1)0的0次方是无意义的,非法输入;
2)0的负数次方相当于0作为除数,也是无意义的,非法输入;
3)base如果非0,如果指数exponent小于0,可以先求base的|exponent|次方,然后再求倒数;
4) 判断double类型的base是否等于0不能使用==号。因为计算机表述小树(包括float和double型小数)都有误差,不能直接使用等号(==)判断两个小数是否相等。如果两个数的差的绝对值很小,那么可以认为两个double类型的数相等。
根据以上4个注意点,我们可以写出求指数的程序,代码如下:
#include "stdio.h"
#include <math.h>
#include <cstdlib>
bool g_InvalidInput = false;
bool equal(double num1, double num2);
double PowerWithUnsignedExponent(double base, unsigned int exponent);
double Power(double base, int exponent)
{
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 = PowerWithUnsignedExponent(base, absExponent);
if (exponent < 0)
result = 1.0 / result;
return result;
}
double PowerWithUnsignedExponent(double base, unsigned int exponent)
{
if (exponent == 0)
return 1;
double result = 1.0;
for(int i = 1; i <= exponent; ++i)
result *= base;
return result;
}
bool equal(double num1, double num2) //判断小数是否相等
{
if ((num1 - num2 > -0.0000001)
&& (num1 - num2 < 0.0000001))
return true;
else
return false;
}
更高效的解法:
代码如下:
/* 《剑指Offer——名企面试官精讲典型编程题》代码
著作权所有者:何海涛*/
#include "stdio.h"
#include <math.h>
#include <cstdlib>
bool g_InvalidInput = false;
bool equal(double num1, double num2);
double PowerWithUnsignedExponent(double base, unsigned int exponent);
double Power(double base, int exponent)
{
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 = PowerWithUnsignedExponent(base, absExponent);
if (exponent < 0)
result = 1.0 / result;
return result;
}
double PowerWithUnsignedExponent(double base, unsigned int exponent)
{
if (exponent == 0)
return 1;
if (exponent == 1)
return base;
double result = PowerWithUnsignedExponent(base, exponent >> 1); //用右移运算符代替除以2
result *= result;
if ((exponent & 0x1) == 1) //用位与运算符代替求余运算符
result *= base;
return result;
}
bool equal(double num1, double num2) //判断小数是否相等
{
if ((num1 - num2 > -0.0000001)
&& (num1 - num2 < 0.0000001))
return true;
else
return false;
}
// ====================测试代码====================
void Test(double base, int exponent, double expectedResult, bool expectedFlag)
{
double result = Power(base, exponent);
if (abs(result - expectedResult) < 0.00000001
&& g_InvalidInput == expectedFlag)
printf("Test passed.\n");
else
printf("Test failed.\n");
}
int main()
{
// 底数、指数都为正数
printf("Test1 begins.\n");
Test(2, 3, 8, false);
// 底数为负数、指数为正数
printf("Test2 begins.\n");
Test(-2, 3, -8, false);
// 指数为负数
printf("Test3 begins.\n");
Test(2, -3, 0.125, false);
// 指数为0
printf("Test4 begins.\n");
Test(2, 0, 1, false);
// 底数、指数都为0
printf("Test5 begins.\n");
Test(0, 0, 1, false);
// 底数为0、指数为正数
printf("Test6 begins.\n");
Test(0, 4, 0, false);
// 底数为0、指数为负数
printf("Test7 begins.\n");
Test(0, -4, 0, true);
system("pause");
return 0;
}

代码(牛客网)
class Solution {
public:
/*bool g_InvalidInput = false; //为了区分是出错(0的0次方)时返回的0,还是底数为0时正常运行返回的0,定义全局变量g_InvalidInput
bool equal(double n1, double n2) //判断double或float型小数是否相等的时候,不能直接用==,而是当两个数的差值很小时,认为相等
{
if(n1 - n2 > -0.000001 && n1-n2 <0.000001)
return true;
else
return false;
}
double Power(double base, int exponent) {
if(equal(base,0.0) && exponent == 0) //0的0次方无意义,返回0.0,g_InvalidInput为true
{
g_InvalidInput = true;
return 0.0;
}
unsigned int absexponent;
if(exponent >= 0) //指数大于0
absexponent = (unsigned int) exponent;
else //指数小于0
absexponent = (unsigned int) (-exponent);
double result = 1.0;
for(int i = 1; i <= absexponent; i++)
{
result *= base;
}
if (exponent < 0)
{
result = 1.0 / result;
}
return result;
}*/
bool g_InvalidInput = false; //为了区分是出错(0的0次方)时返回的0,还是底数为0时正常运行返回的0,定义全局变量g_InvalidInput
bool equal(double n1, double n2) //判断double或float型小数是否相等的时候,不能直接用==,而是当两个数的差值很小时,认为相等
{
if(n1 - n2 > -0.000001 && n1-n2 <0.000001)
return true;
else
return false;
}
double PowerWithUnsignedExponent(double base, int absexponent)
{
if(equal(absexponent, 0.0))
return 1.0;
if(equal(absexponent, 1.0))
return base;
double result = PowerWithUnsignedExponent(base, absexponent>>1);
result *= result;
if(absexponent & 0x1)
result *= base;
return result;
}
double Power(double base, int exponent) {
if(equal(base,0.0) && exponent == 0) //0的0次方无意义,返回0.0,g_InvalidInput为true
{
g_InvalidInput = true;
return 0.0;
}
unsigned int absexponent;
if(exponent >= 0) //指数大于0
absexponent = (unsigned int) exponent;
else //指数小于0
absexponent = (unsigned int) (-exponent);
double result = PowerWithUnsignedExponent(base,absexponent);
if (exponent < 0)
{
result = 1.0 / result;
}
return result;
}
};