C++代码编程的一个小插曲

107 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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也有这个显示的问题,在高精度的计算中,还是不能简单的看这个表面的输出数据,还需要注意其对应的精度问题!!!