题目:求多项式的根
要求a用屏幕进行输入,根的精度为0.0000001,可能无解
样例输入:
input:
5
样例输出
ouput:
-1.068617
-0.593694
思路:使用牛顿迭代法进行求解,同时通过记录已有根剔除重复根,驻点直接由定义判断。
#include<cstdio>
#include<cmath>
double a;
double abs(double x)
{
if(x >= 0) return x;
else return -x;
}
double f(double x)
{
return a * pow(x,11) - 3 * pow(x,8) - 5 * pow(x,3) - 1 ;
}
double fd(double x)
{
return 11*a * pow(x,10) - 8*3 * pow(x,7) - 3*5 * pow(x,2) ;
}
double esp = 1E-7;
int maxn = 1/esp/2;
int main()
{
scanf("%f",&a);
double stk[10000];int top = -1;
//int k[10000],m[10000],sum = 0;
double x0;
for(x0 = -5000;x0 <= 5000;x0++)
{
int count = 0;
double x1 = x0;
int x;
int flag = 1;
while(abs(f(x1)) > esp&&abs(x1 - x) > esp&&count < maxn)
{
//sum++;
x = x1;
if(fd(x1) == 0)
{
if(abs(f(x1)) <= esp) break;
else
{
flag = 0;
break;
}
}
x1 = x1 - f(x1) / fd(x1);
//printf("%f \n",x1);
count++;
}
if(abs(f(x1)) > esp) flag = 0;
for(int i = 0;i < 10000;i++)
{
if(abs(stk[i] - x1) < esp)
{
flag = 0;
break;
}
}
if(count != maxn && flag)
{
//printf("\n\n%d::%f \n",top+1,x1);
stk[++top] = x1;
//k[top] = count;
//m[top] = sum;
}
}
if(top == -1) printf("*****none*****");
for(int i = 0;i < top + 1;i++)
{
printf("%f\n",stk[i]);
//printf("****%d***@%d-%d/%d******%f****%f*****\n",i + 1,k[i],m[i],sum,stk[i],f(stk[i]));
}
return 0;
}
附记: 另解见https://www.jianshu.com/p/687a10368d00 ,但该程序有错
附代码:
#include <stdio.h>
#include <math.h>
/**
* 牛顿迭代求根
*/
//带入原函数后所得的值
double f(double a, double x)
{
return (a*pow(x,11)-3*pow(x,8)-5*pow(x,3)-1)/1.0;
}
//带入一阶导函数后所得的值
double f1(double a, double x)
{
return (a*11*pow(x,10)-24*pow(x,7)-15*pow(x,2))/1.0;
}
//牛顿迭代函数
double F(double a, double x)
{
double x1;
x1=x-1.0*f(a, x)/f1(a, x);
return (x1);
}
int main() {
// ax^11 - 3x^8 - 5x^3 - 1 = 0
double x0=20.0,D_value=0.0,x1=0.0,a=0.0;
printf("ax^11 - 3x^8 - 5x^3 - 1 = 0\n请输入a: ");
scanf("%lf", &a);
printf("\n\na为:%lf", a);
do {
x1=F(a, x0);
D_value=fabs(x1-x0);
x0=x1;
} while((D_value<=0.0000001));
printf("\n\n结果为:%lf", x1);//原作者此处有错
//debug//printf("%f",f(a,x1));
printf("\n\n");
return 0;
}
a = 5时,插入原函数f(a,x1)验算
//debug//printf("%f",f(a,D_value));
ax^11 - 3x^8 - 5x^3 - 1 = 0 请输入a: a为:5.000000 结果为:18.181855 358878000599541.312500
原因:牛顿迭代法在区间设置不合理时可能无法收敛,原作者错用
注:牛顿迭代法收敛判断:①f(x) <esp② |x0 - x1| <= eap ③驻点时,牛顿迭代法失效,要在迭代前直接使用f(x) <esp 判断;