【c++】写一个函数,实现x的y次方
2015-08-21 13:30
651 查看
写一个函数,实现x的y次方
乍一看会觉得很简单,一个for循环就搞定了
但这样做,没有考虑到指数是负数的情况,也没有考虑到如果base是0,指数是负数没有数学意义的情况。
稍加考虑我们可以写出下面的代码:
以及比较两个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,直到递归结束。
单元测试:把底数和指数分别设为正数,负数和0.
乍一看会觉得很简单,一个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.
相关文章推荐
- [黑马程序员]C语言内存管理
- C语言优先级总结
- [C++] String to Integer (atoi)
- c++ 堆和栈的简析
- TIOBE(2015.8):Java、C和C++持稳前三,OC依然在Top 5之外
- C++中的case标签
- Effective c++读书笔记
- C语言feof函数的一个简单示例
- C语言中的函数指针
- C语言中sscanf 的详细用法
- C++编译、链接涉及到的一些基本问题
- C++ 11: 右值引用,转移语义与完美转发
- C/C++中的常量指针与指针常量(转)
- c++ 重载== 相关
- [C++]Valid Palindrome 有效回文
- C++/winapi截屏保存BMP
- ::和.的区别
- 终于完成了Josephus的C语言实现啦~~
- IIR 滤波器的实现(C++)
- C++ STL std::pair