开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情
入职新公司,把大一扔下的C++要重新捡起来,今天在学习的时候遇到一个C++实现二分法求解方程根的问题,顺便记录下
题目要求比较简单,就是用二分法求解一个方程组在特定范围的根,要求误差小于0.00001.
方程组为:x^9-4x^5-5x^3-270000=0,范围为0~10;
C++代码方式:
#include <iostream>#include "math.h"#include <iomanip>using namespace std;using std::cin;using std::cout;using std::endl;
int main() { double x; double x1(0),x2(10),y0, y1; double tol; do{ x = (x1+x2)/2; tol = pow(x,9)-4*pow(x,5)-5*pow(x,3)-270000; cout<<tol<<endl; y0 = pow(x1,9)-4*pow(x1,5)-5*pow(x1,3)-270000;
y1 = pow(x2,9)-4*pow(x2,5)-5*pow(x2,3)-270000; cout<<tol<<" " <<y0<<" " <<y1<<" " <<endl; if (tol*y0<0){ x2 = x; } else{ x1 = x; } if (x1==x2){ break; } cout<<x1<<", " <<x2<<" " <<endl; } while (fabs(tol)>0.00001); cout<<x<<endl; return 0;}
cout是我调试用的,便于实时看看结果
输出结果可以看到为4.02057
为了验证我的结果是否正确,我在用matlab自带的fsolve函数来求解一遍
>> x = fzero("x^9-4*x^5-5*x^3-270000",2);>> x
x =
4.0206 >> x^9-4*x^5-5*x^3-270000
ans =
-5.8208e-11
和我的结果很接近,而且这个误差符合要求,但我把C++的计算结果4.02057带入方程组去计算,发现这个误差值为1.897,和预计的相差较大,
>> x = 4.02057
x =
4.0206
>> x^9-4*x^5-5*x^3-270000
ans =
1.8973
仔细查看了一下C++的cout过程,可以发现C++计算的tol是符合要求的,小于0.00001,那最大的可能性就是显示的问题了,查阅资料得到:
cout输出时,默认double只能显示6位有效数字
为了得到准确的时候需要增加cout的输出位数
#include <iostream>#include "math.h"#include <iomanip>using namespace std;using std::cin;using std::cout;using std::endl;
int main() { double x; double x1(0),x2(10),y0, y1; double tol; do{ x = (x1+x2)/2; tol = pow(x,9)-4*pow(x,5)-5*pow(x,3)-270000; cout<<tol<<endl; y0 = pow(x1,9)-4*pow(x1,5)-5*pow(x1,3)-270000;
y1 = pow(x2,9)-4*pow(x2,5)-5*pow(x2,3)-270000; cout<<tol<<" " <<y0<<" " <<y1<<" " <<endl; if (tol*y0<0){ x2 = x; } else{ x1 = x; } if (x1==x2){ break; } cout<<x1<<", " <<x2<<" " <<endl; } while (fabs(tol)>0.00001); cout<<setprecision(13) <<x<<endl; return 0;}
此时的x为:4.020566884828,在matlab中计算一下
>> x = 4.020566884828
x =
4.0206
>> x^9-4*x^5-5*x^3-270000
ans =
1.7846e-07
同样的,matlab也有这个显示的问题,在高精度的计算中,还是不能简单的看这个表面的输出数据,还需要注意其对应的精度问题!!!