#include<stdio.h>
#include<math.h>
#define accuracy 0.00001
#define check -1530494977
void tell()
{
printf("本程序用于求解一元高次方程\n");
printf("注意事项:\n");
printf("1、本程序所求根均为近似解,精度可通过改变宏来调整\n");
printf("2、请保证方程形如∑(i=0,n)(a_i*x^i)=0,a_i为整数\n");
printf("3、请保证方程的根取值范围为(-1215752191,276447231)\n");
printf("使用方法:\n");
printf("1、先将方程反复求导,直至将方程化为一元二次方程\n");
printf("2、解出一元二次方程的解\n");
printf("3、输入方程根的上下限,等待计算机求出结果\n");
printf("4、以此循环,直至求出方程的全部解\n");
printf("求解原理:\n");
printf("导数根为其原函数的极值点,由于多项式函数的两个极值点内最多只有一个根,所以可以逐步逼近方程的根\n");
}
void solve_equation_tow(int a,int b,int c)
{
float delta,x1,x2,check_number=1,s=1;
delta = (b*b)-(4*a*c);
if(delta<0)
{
printf("该方程没有实数解\n");
}
else if(delta==0)
{
printf("该方程的解为x1=x2=%f\n",x1);
}
else
{
x1=(-b+sqrt(delta))/(2*a);
x2=(-b-sqrt(delta))/(2*a);
printf("该方程的解为:\nx1=%f\nx2=%f\n\n\n",x1,x2);
}
}
float f(float x,int time,int da[time+1])
{
int i=0;
float y=0;
while(i<time+1)
{
y=y+da[i]*pow(x,i);
i++;
}
return y;
}
float close_to_x(float x_lower_limit,float x_upper_limit,int time,int da[time+1])
{
float x,y,y_left,y_right,p;
int i=1;
x = (x_lower_limit+x_upper_limit)/2;
y_left = f(x_lower_limit,time,da);
y_right = f(x_upper_limit,time,da);
y = f(x,time,da);
if(y_left*y_right>0) return check;
else{
if (y_left>y_right)
{
while(y>accuracy||y<-accuracy)
{
if(y>accuracy) x_lower_limit = x;
if(y<-accuracy) x_upper_limit = x;
x = ( x_lower_limit+x_upper_limit)/2;
y = f(x,time,da);
if(x_upper_limit-x_lower_limit<=0.000001) break;
}
}
if (y_right>y_left)
{
while(y>accuracy||y<-accuracy)
{
if(y>accuracy) x_upper_limit = x;
if(y<-accuracy) x_lower_limit = x;
x = ( x_lower_limit+x_upper_limit)/2;
y = f(x,time,da);
if(x_upper_limit-x_lower_limit<=0.000001) break;
}
}
return x;
}
}
int der(int n,int a[n],int time)
{
int da[time+1],i=n-1,d=1,t,m;
for(t=0;t<time+1;t++) da[t]=1;//对数组元素初始化
for(m=0;m<=time;m++)
{
while(i>time-m)
{
d=i*d;
i--;
}
da[time-m]=d*a[n-m-1];
i=n-1-m-1;
d=1;
}
if(time==n-1) printf("最初待求原方程为:\n");
else printf("当方程求导到%d次后,方程为:\n",time);
for(i=time;i>0;i--) printf("(%dx^%d)+",da[i],i);
printf("(%d)=0\n",da[0]);
if(time==2) solve_equation_tow(da[2],da[1],da[0]);
else
{
float root[time];
float x_lower_limit,x_upper_limit;
int s;
for(s=0;s<time;s++)
{
int t;
printf("正在尝试求解根x%d\n",s+1);
printf("请输入x的下限:");
scanf("%f",&x_lower_limit);
printf("请输入x的上限:");
scanf("%f",&x_upper_limit);
root[s]=close_to_x(x_lower_limit,x_upper_limit,time,da);
if (root[s]==check) printf("该方程在此区域内无实数解\n");
else printf("x%d=%f\n",s+1,root[s]);
}
printf("该%d次方程的解为:\n",time);
int z,q=1;
for(z=0;z<time;z++)
{
if(root[z]!=check) printf("x%d=%f\n",q,root[z]);
q++;
}
}
printf("\n\n\n");
}
void main()
{
tell();
int n,p;//p是方程非常数项数量,同时是方程最高次项次数,n是方程总项数
printf("\n\n\n请输入方程的最高次数:");
scanf("%d",&p);
n=p+1;
int a[n],i;//a[n-1]是方程n-1次项系数,i用于后期计数
for(i=0;i<n;i++) //此循环用于输入各项系数
{
if(i==0) printf("请输入常数项的值:");
else printf("请输入%d次项的值:",i);
scanf("%d",&a[i]);
}
printf("该方程为:");
for(i=n-1;i>0;i--) printf("(%dx^%d)+",a[i],i);//打印方程,用于纠错
printf("(%d)=0\n",a[i]);//本行用于打印方程常数项
float x,y;
printf("\n\n\n");
for(i=3;i<=n;i++) der(n,a,i-1);
}