实数二分法求解一元三次方程

实数二分是最简单的二分,可以直接除以2!!

计算当前函数值和0进行比较,如果f(x)正好是0或者和0的距离很小,此时的x就算是方程的解,f(x)的计算很容易给出

double f(double x)
{
    return ((a*x+b)*x+c)*x+d;
}

接下来是递归二分部分,当然这里容易爆栈强烈建议使用非递归形式,懒得写了O(∩_∩)O

void ef(double l,double r)
{
    double m=(l+r)/2;
    if(abs(f(m))<0.0001)
    {
        ans[++tot]=l;
        return;
    }
    if(f(l)*f(m)<0)
        ef(l,m);
    else
        ef(m,r);
}

首先取x值中点m,然后判断当前m处函数值,如果满足结果直接计入ans,如果不满足,就计算f(l)*f(m)来决定是往左区间走还是右区间走。

完整的代码如下,输入a,b,c,d之后就可以求解了,代码中将整个区间进行了均分,只有区间内端点处函数值乘积为负才有解,否则二分法找不到解。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 using namespace std;
 5 double a,b,c,d;
 6 double ans[6];
 7 int tot=0;
 8 double f(double x)
 9 {
10     return ((a*x+b)*x+c)*x+d;
11 }
12 void ef(double l,double r)
13 {
14     double m=(l+r)/2;
15     if(abs(f(m))<0.0001)
16     {
17         ans[++tot]=l;
18         return;
19     }
20     if(f(l)*f(m)<0)
21         ef(l,m);
22     else
23         ef(m,r);
24 }
25 int main()
26 {
27     cin>>a>>b>>c>>d;
28     for(int i=-100;i<100;i++)
29     {
30         double l=double(i);
31         double r=l+0.9999;
32         if((abs(f(l)))<0.0001)
33         {
34             ans[++tot]=l;
35             continue;
36         }
37         else if(f(l)*f(r)<0)
38             ef(l,r);
39     }
40     for(int i=1;i<=3;i++)
41         printf("%.2lf ",ans[i]);
42     cout<<endl;
43     return 0;
44 }

猜你喜欢

转载自www.cnblogs.com/aininot260/p/9270867.html