C++|关于pow函数误差的一个例子
今天在刷题时遇到了下述问题:

很明显,就是一个循环的练习。
1 #include <iostream> 2 #include <cstdlib> 3 #include <ctime> 4 #include <cmath> 5 using namespace std; 6 7 bool isNum(int n) 8 { 9 int sum = 0; 10 11 for (int k = n; k > 0; k /= 10) 12 { 13 sum += pow((k % 10),3); 14 } 15 16 if (sum == n) 17 return true; 18 else 19 return false; 20 } 21 22 int main() 23 { 24 int a, b; 25 cin >> a >> b; 26 for (int i = a; i <= b; i++) 27 { 28 if (isNum(i)) 29 cout << i << endl; 30 } 31 system("pause"); 32 return 0; 33 }
写完以上之后,测试了一组数据a=100,b=1000,但是答案和实际的却相差一个153,试了几次都是如此,调试之后发现是5^3出了问题,应该是125,但它却给出了124这个结果。
网上查阅资料后发现大概是浮点误差引起的问题。
pow()返回类型是double, 循环计数i与 pow()比较的时候将被转换为两个double比较,于是就出现了边界问题。
pow的计算方式,存在误差,就是说pow(5,2);这条代码,实际上是25,但是由于算法问题很可能返回的值是24.9999,然后转化为整型,变成了24。
以后还是尽量避免在整型中使用pow函数吧。
简单修改之后的程序:
1 #include <iostream> 2 #include <cstdlib> 3 #include <ctime> 4 #include <cmath> 5 using namespace std; 6 7 bool isNum(int n) 8 { 9 int sum = 0; 10 11 for (int k = n; k > 0; k /= 10) 12 { 13 sum += (k % 10) * (k % 10) * (k % 10); 14 } 15 16 if (sum == n) 17 return true; 18 else 19 return false; 20 } 21 22 int main() 23 { 24 int a, b; 25 cin >> a >> b; 26 for (int i = a; i <= b; i++) 27 { 28 if (isNum(i)) 29 cout << i << endl; 30 } 31 system("pause"); 32 return 0; 33 }
写点代码,读点小诗,慢点生活。

浙公网安备 33010602011771号