-
题目描述:
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
-
分析:
首先这个题的思路很简单,求base的整数次方,那么只要用exponent个base相乘就好了。基本的思路有了,接下来就要举测试用例来考虑有没有特殊情况了:当指数为零和负数的时候。
先是指数为零,除零外任何数数的零次幂都是1,零的零次幂没有意义;而指数为负数的时候,即求base的倒数,若base不为零,只要先求exponent的绝对值个base的积,然后返回结果的倒数即可。若指数为负而base为零那么求其倒数就是错误的运算,所以这时候应该做错误处理。这里总结一下函数中错误处理的三种方法:
- 函数用返回值来告诉调用者是否出错。
这与很多Windows的API一直。但是这么做的缺点是不能将函数的计算结果作为返回值使用,即不能作为返回值赋值给其他变量或者直接作为参数传递给其他函数。 - 设置全局变量。
这种方法就是用全局变量来标记程序是否出错,比如剑指offer中常用bool型的g_Invalidinput作为全局变量来表示非法输入。这个方法存在的缺陷是调用者很可能忘记去检查全局变量而造成出错时没有进行错误处理。 - 异常
当函数出错的时候就抛出一个异常,还可以根据出错的原意定义不同的异常类型。这种方法的缺陷是有些语言不支持,另外,抛出异常时程序的执行会打乱正常的顺序,造成对性能的影响。
code:
bool g_Validinput = false; double Power(double base, int exponent) { g_Validinput = false; bool flag = false; if (abs(base - 0.0) < 0.0000001 && exponent <= 0) { g_Validinput = true; return 0.0; } unsigned int absexponent = 0; if (exponent < 0) { flag = true; // 这里值得注意! // 把absexponent定义成unsigned型是因为int型中负数比正数多一个 absexponent = (unsigned int)(-exponent); } else absexponent = (unsigned int)exponent; double result = 1.0; for (int i = 1; i <= absexponent; ++i) result *= base; if (flag) return 1.0 / result; else return result; }
其中值得注意的有两点:
第一,在判断base是否为零的时候没有用base == 0,是因为在计算机中小数的存储存在误差,不能使用==来判断float、double等小数,取而代之的是和0的差值小于0.0000001就认为是0。
第二,在求指数幂的时候,若exponent为负,那么取其绝对值的时候要注意,int中负数比正数多一个,当exponent为最小负数(即0x80000000)时,其绝对值用int是放不下的,所以absexponent定义成了unsigned int型。 - 函数用返回值来告诉调用者是否出错。