您的位置:首页 > 编程语言 > C语言/C++

【c++】写一个函数,实现x的y次方

2015-08-21 13:30 651 查看
写一个函数,实现x的y次方

乍一看会觉得很简单,一个for循环就搞定了

<span style="font-family:Microsoft YaHei;">double result = 1.0;
for (int i = 1; i <= exponent; i++) {
result *= base;
}
return result;</span>


但这样做,没有考虑到指数是负数的情况,也没有考虑到如果base是0,指数是负数没有数学意义的情况。

稍加考虑我们可以写出下面的代码:

/*
* pow.cpp
*
*  Created on: 2015?8?20?
*      Author: nanzhou
*/
bool g_InvalidInput = false;
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) {
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 && (num2 - num1) > 0.0000001 )
return true;
else
return false;
}
注意代码的模块化,我们把求指数为绝对值的功能和判断两个double型数据的功能分开来写。

以及比较两个double型数字是不是相等不是通过num1 == num2来实现的,因为double和float数据在计算机里不是完全相等的,equal()函数里通过比较两者只差小于一个极小数来实现。

另外,我们设置了一个全局变量g_InvalidInput 来判断输入是否合法,如果不合法,g_InvalidInput 会被设置为true。这样做的好处是,我们可以把函数的返回值直接传给其他变量,对程序的执行逻辑和性能没有影响,但缺点是可能会忘了检查这个全局变量。

这样是不是可以称得上“完美”了呢?在PowerWithUnsignedExponent()里,通过累乘来计算幂运算,如果计算一个数的32次幂,我们要计算31次乘法,效率也真够低的。换一种思维,32次幂是16次幂的平方,平方可以通过左移一位来实现,以此类推,16次幂是8次幂的平方...直到递归终止在次幂为1或0,而一个数的1次幂是其本身,0次幂是1.

也就是,如果exponent是偶数,base的exponent可以表示为base的exponent/2次幂的平方

那如果次幂exponent是奇数,base的exponent可以表示为base的(exponent-1)/2次幂的平方再乘以base,直到递归结束。

double PowerWithUnsignedExponent(double base, unsigned int exponent) {
if (exponent == 0) return 1;
if (exponent == 1) return base;
double result = PowerWithUnsignedExponent(base, exponent >> 1);
result *= result;
if (exponent & 0x1 == 1) //exponent is odd
result *= base;
return result;
}

单元测试:把底数和指数分别设为正数,负数和0.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: