求方程x*x*x+1.1*x*x+0.9*x-1.4=0的近似根
一、二分法
using namespace std;
double f(double x)
{
double k=x*x*x+1.1*x*x+0.9*x-1.4;
return k;
}
int main()
{
double left,right,mid;
cin>>left>>right; //手动输出方程根所在的区间
mid=left+(right-left)/2;
while(fabs(f(mid))>1e-6)
{
if(f(mid)>0)
{
right=mid;
}
else
{
left=mid;
}
mid=left+(right-left)/2;
//cout<<mid<<endl;
}
cout<<mid<<endl;
return 0;
}
二、切线法
思想:从纵坐标与f''(x)同号的那个端点处x0做切线,与x轴相交于点x1,若f(x1)足够接近0则算法结束,否则继续从(x1,f(x1))处做切线又与x轴相交与x2,再继续判断.....
公式:X(n+1)=Xn-f(Xn)/f'(Xn)
double f(double x) //函数f(x)
{
double k=x*x*x+1.1*x*x+0.9*x-1.4;
return k;
}
double f_de(double x,int i) //函数f(x)导数
{
double k;
if(i==1) //一阶导数
k=3*x*x+2.2*x+0.9;
else //二阶导数
{
k=6*x+2.2;
}
return k;
}
int main()
{
double left,right;
double x0;
cin>>left>>right;
if(f_de(left,2)*f(left)>=0) //f''(x)与f(left)同号
{
x0=left; //从(left,f(left))点做切线
}
else //f''(x)与f(right)同号
{
x0=right; //从(right,f(right))点做切线
}
while(fabs(f(x0))>1e-6)
{
x0=x0-f(x0)/f_de(x0,1);
}
cout<<x0<<endl;
return 0;
}
三、割线法
思想:利用切线法计算函数的导数,当f(x)比较复杂时,计算其导数可能有点困难,这时,可以用
(f(xn)-f(xn-1))/(xn-xn-1)
来代替切线法公式中的f'(x),这时迭代公式变为:
X(n+1)=Xn-(Xn-Xn-1)/(f(Xn)-f(Xn-1)) *f(Xn);
double f(double x) //函数f(x)
{
double k=x*x*x+1.1*x*x+0.9*x-1.4;
return k;
}
int main()
{
double x0,x1; //用过该两点的直线代替切线法某端点的切线
cin>>x0>>x1;
double x2; //x0,x1两点直线与X轴交点
x2=x1-(x1-x0)/(f(x1)-f(x0))*f(x1);
while(fabs(f(x2))>1e-6)
{
x0=x1;
x1=x2;
x2=x1-(x1-x0)/(f(x1)-f(x0))*f(x1);
}
cout<<x2<<endl;
return 0;
}