《剑指offer》【面试题11:数值的整数次方】

面试题11:数值的整数次方

我们一般从程序的正确性和鲁棒性来检验代码的质量,会关注对输入参数的检查、处理错误和异常的方式、命名方式等。

代码的规范性:
【清晰的书写、 清晰的布局、 合理的命名 】=【规范的代码】
代码的测试:
【功能测试、 边界测试、 负面测试】 =》 【完整的代码】

代码3种错误的处理方法:
1.函数用返回值来告知调用者是否出错;
2.当发生一个错误时用一个全局变量进行标记
3.异常处理,函数出现错误,就抛出一个异常

代码三种错误方法的比较:


面试题11:数值的整数次方:
题目: 实现函数double Power(double base, int exponent),求base的exponent次   方。不得使用 库函数,同时不需要考虑大数问题。

注意:考虑特殊情况,底数和指数的特殊值,以及一些细节,先看代码,测试用例就是最好的分析。
图解:

代码实现:

#include <iostream>
#include <assert.h>
using namespace std;

//判断double类型的两个数字是否相等
bool Equal(double num1, double num2)
{
	bool flag = false;
	if(num1-num2 > -0.000001 && num1-num2 < 0.000001)
	{
		flag = true;
	}
	return flag;
}

double PowerwithUnsignedExponent(double base, unsigned int exponent)
{
	if(exponent == 0)
	{
		return 1;
	}
	if(exponent == 1)
	{
		return base;
	}
	//exponent >> 1 等同于 exponent/2  ,位运算比乘除法等计算效率高
	double result = PowerwithUnsignedExponent (base, exponent >> 1);//递归计算
	result *= result;
	//类似于判断exponent的奇偶性,位运算比乘除法等计算效率高
	if(exponent & 0x1 == 1)
	{
		result *= base;
	}
	return result;
}

double Power(double base, int exponent)
{
	double result = 0.0;
	assert(base > 0.000001 || base < -0.000001);//底数不能为0
	/*
	//比较double类型的数字,用assert直接进行了处理,相当于优化
	if (Equal(base,0.0))
	{
		//cout <<"底数不能为0"<<endl;
	}
	*/
	//保存指数,为了防止指数为负数,保存下来,下面执行的时候统一计算,节省空间
	double exponent_1 = exponent;
	if (exponent < 0)
	{
		 exponent_1 *= -1;
	}
	result = PowerwithUnsignedExponent(base, exponent_1);//统一计算指数为负数和正数的情况
	if (exponent < 0)//再次判断,对上一次的值进行求倒数
	{
		result = 1.0/result;
	}

	return result;
	
}
int main()
{
/*-----------------------面试题10:数值的整数次方---测试用例---------------------------*/
	
	//底数为正数,指数为正数
	double base = 2.0;
	int exponent = 5;
	cout<<"底数为"<<base<<"指数为"<<exponent<<"的值为:  "<<Power(base, exponent)<<endl;
	
	//底数为正数,指数为0
	double base1 = 2.0;
	int exponent1 = 0;
	cout<<"底数为"<<base1<<"指数为"<<exponent1<<"的值为:  "<<Power(base1, exponent1)<<endl;
	
	//底数、指数均为0
	/*
	double base2 = 0.0;
	int exponent2 = 0;
	cout<<"底数为"<<base2<<"指数为"<<exponent2<<"的值为:  "<<Power(base2, exponent2)<<endl;
	*/
	
	//底数为0.0,指数不为0
	/*
	double base3 = 0.0;
	int exponent3 = 1;
	cout<<"底数为"<<base3<<"指数为"<<exponent3<<"的值为:  "<<Power(base3, exponent3)<<endl;
	*/

	//底数、指数均为负数
	double base4 = -1.0;
	int exponent4 = -1;
	cout<<"底数为"<<base4<<"指数为"<<exponent4<<"的值为:  "<<Power(base4, exponent4)<<endl;
	
	//底数为负数,指数为正数
	double base5 = -1.0;
	int exponent5 = 5;
	cout<<"底数为"<<base5<<"指数为"<<exponent5<<"的值为:  "<<Power(base5, exponent5)<<endl;
	
	//底数为正数,指数为负(偶)数
	double base6 = 2.0;
	int exponent6 = -2;
	cout<<"底数为"<<base6<<"指数为"<<exponent6<<"的值为:  "<<Power(base6, exponent6)<<endl;
	
	//底数为正数,底数为负(奇)数
	double base7 = 2.0;
	int exponent7 = -5;
	cout<<"底数为"<<base7<<"指数为"<<exponent7<<"的值为:  "<<Power(base7, exponent7)<<endl;
	
	cout<<endl;
	return 0;
}
上述的注意点:
对于底数是否为0判断时和位运算代替乘除法及求余运算是两个加分点,需要注意。补充一句:好的代码不只是函数功能的实现,还有它的效率以及简洁,并且你会发现测试用例有时候是相当重要的。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值