1.代码质量:资源回收、异常状况、对“正常值”进行的处理、功能错误、边界情况。
2.规范的代码:清晰的书写、布局、命名
3.关键是在写代码之前形成清晰的思路,并能把思路用编程语言清楚地写出来。
4.单元测试的设计:负面测试(即错误的输入)、功能测试、边界测试。
5.三种错误处理的方法,各有优缺点:
a.函数返回值。优:和系统一致。缺:不能方便的计算结果。
b.全局变量。优:函数返回值依然可以设置为结果,能够方便的使用计算结果。缺:用户可能忘记检查全局变量。
c.异常,try catch块。 优:可以为不同的出错原因定义不同的出错原因定义不同的异常类型,逻辑清晰明了。 缺:有些语言不支持异常,抛出异常时对性能有负面影响。
题目描述:实现函数double Power(double base, int exponent),求base的expontent次方。不能使用库函数,同时不需要考虑大数问题。
解题思路:
- 一个数值m的n次方等于n个m相乘,如:5^3 = 5*5*5; 所以无论n等于几都是m的自乘。若m为负数,需要取倒数。
- 指数为负数的时候,应先去绝对值,求出指数的结果之后,再求倒数。
- 0的0次方和0的负数次方无意义。
测试用例:
int main(){
//(0.0 , 0)次方
double res = Power(0.0, 0);
if(g_InvalidInput) //记得检查全局变量
std::cout << "(0.0, 0) : " << res << std::endl;//Output: 1
else
std::cout << "Invalid Input\n";
//(3.3, 3)次方
res = Power(3.3, 3);
if(g_InvalidInput)
std::cout << "(3.3, 3) : " << res << std::endl; //Output: 35.937
else
std::cout << "Invalid Input\n";
//(3.3, 0)次方
res = Power(3.3, 0);
if(g_InvalidInput)
std::cout << "(3.3, 0) : " << res << std::endl; //Output: 1
else
std::cout << "Invalid Input\n";
//(-3.3, 0)次方
res = Power(-3.3, 0);
if(g_InvalidInput)
std::cout << "(-3.3, 0) : " << res << std::endl; //Output: 1
else
std::cout << "Invalid Input\n";
//(0.0, -2)次方
res = Power(0.0, -2);
if(g_InvalidInput)
std::cout << "(0.0, -2) : " << res << std::endl; //Output: Invalid Input
else
std::cout << "Invalid Input\n";
return 0;
}
函数实现:
#include <iostream>
//全局变量(检查错误处理的方法)
bool g_InvalidInput = true; //默认合法,缺点:需要在client检查全局变量。此举是为了区分底数为0的时候正常返回0还是出错的时候返回0。
//判断double值是否等于0
bool equal(double num1, double zero){
//对于小数,将他们两个相减。结果若在一个极小的范围内,那么我们认为它们相等
if( (num1 - zero > -0.0000001) && (num1 - zero) < 0.0000001)
return true;
else
return false;
}
//迭代版解法
double PowerWithUnsignedExponent(double base, double exponent){
if(exponent == 0)
return 1;
if(exponent == 1)
return base;
double result = 1.0;
for(auto i = 1; i <= exponent; ++i)
result *= base;
return result;
}
//递归版解法
double RPowerWithUnsignedExponent(double base, unsigned int exponent){
if(exponent == 0)
return 1;
if(exponent == 1)
return base;
double result = RPowerWithUnsignedExponent(base, exponent >> 1);
result *= result;
if(exponent & 0x1 == 1)
result *= base;
return result;
}
//主函数
double Power(double base, int exponent){
if(equal(base, 0.0) && exponent < 0){ //判断base是否为0,在浮点数情况下无法直接和0比较,采取比较一个极小数来确定base是否为0
g_InvalidInput = false; //不合法
return 0.0; //由于不合法返回的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;
}