一元n次方程求解程序

#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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值