pow()函数自实现

来源:互联网 发布:小镇姑娘 知乎 编辑:程序博客网 时间:2024/06/05 02:42

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

其实这道题就是要实现pow这个库函数。你可不要自以为这道题目简单,直接给出一个for循环了事。像下面这样:

double power(double base, int exponent){double result = 1.0;int i = 0;for (i = 0; i < exponent; i++){result *= base;}return result;}

初看起来貌似没有问题,不过遗憾的是并没有考虑到所有的输入的情况。如果输入的指数小于1那怎么办?这段代码完全没有考虑这些意外!

同时,这段代码的效率高吗?不高。我们是否还有更好的解法,答案是肯定的!假设求a的n次方,当n为偶数时,a的n次方可以由两个a的n/2次方相乘求得;当n为奇数时,a的n次方可以由两个a的n/2次方相乘的积再乘以a得到。

由此,我们可以写出如下鲁棒又高效的代码:

int equal(double elem1, double elem2){if ((elem1 - elem2 < 0.0000001) && (elem1 - elem2 > -0.0000001))return 1;//相等elsereturn 0;//不相等}double power_unsigned_exp(double base, unsigned int exponent){double result = 0.0;if (0 == exponent)return 1.0;if (1 == exponent)return base;result = power_unsigned_exp(base, exponent / 2);if (exponent & 1 == 1)result *= base;return result;}double power(double base, int exponent){unsigned int abs_exponent = exponent;double result = 0.0;invalid_input = 0;if (equal(base, 0.0) && exponent < 0){invalid_input = 1;return 0.0;}if (exponent < 0)abs_exponent = (unsigned int)(-exponent);result = power_unsigned_exp(base, abs_exponent >> 1);result *= result;if (result < 0)result = 1.0 / result;return result;}

这段代码中还有其它的优点。比如,要求exponent的一半是,使用了右移一位的操作,而不是简单的除以2,提升了效率;再比如,判断exponent的奇偶性是也是使用了位操作;还有,浮点数与浮点数的比较不能直接用==比较,牵扯到精度的问题。

最后一点,用了一个全局变量来标识是否出错。我们可以采用3种错误处理方法方法:返回值,全局代码和异常。这三种方法各有优缺点,需要自己权衡。下面简单的列出几种错误处理方式的优缺点:

返回值 优点:和系统API一致;缺点:不能方便地使用计算结果。

全局变量 优点:能够方便地使用计算结果;缺点:用户可能会忘记检查全局变量。

异常 优点:可以为不同的出错原因定义不同异常类型,逻辑清晰明了;缺点:有些语言不支持异常,抛出异常时对性能由负面影响。



1 0
原创粉丝点击