C语言解一元二次方程

特点
  1. 不同于大多数程序,结果可保留根号
  2. 可输入小数,输入小数会自动通分成整数
  3. 根式自动化简系数是1会省略
  4. 结果可输出虚数
  5. 打开一次程序可计算多次
解一个方程的流程
  1. 输入a,b,c值
  2. a,b,c中若有小数便转为整数
  3. 计算出delta并化为最简二次根式
  4. 计算出2a,-b的值并约分
  5. 按照代数格式输出
  6. 输出根的近似值
要点
  1. 函数 print1() 和函数print2()用来按代数格式输出
  • 此部分较为庞大,本人目前没想到简单的方法,若有大佬想到可在评论区提建议
  1. 函数simplify()用来化简二次根式(Δ\sqrt{Δ}Δ )
  2. 数学上原求根公式为x=−b±b2−4ac2ax=\frac{-b±\sqrt{b^2-4ac}}{2a}x=2ab±b24ac ,用本程序中的变量表示为x=b±sd∗pax=\frac{b±sd\sqrt{*p}}{a}x=ab±sdp x=b±sddeltaax=\frac{b±sd\sqrt{delta}}{a}x=ab±sddelta
    (a,b为变化后的2a,-b)
  3. main()函数10~13行的部分用来将小数利用等式的性质变为整数,再赋给a,b,c
效果
  • 这里只放两张图,可以自己复制代码后尝试
  • 注意:测试的清空缓冲区命令fflush(stdin);在Termux这里不可用,电脑上测试(我用的dev-c++)时可用。因此这两张图上“是否继续”会直接跳过,在电脑上使用不会出问题
    3个方程测试
    3个方程测试
代码区(欢迎复制)
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int simplify(int *p)//化简二次根式
{
    *p=abs(*p);
	int i,m=1;
	if(*p==0)
		return 0;
	for(i=2;i<=sqrt(*p);)
		if(*p%(i*i)==0)
		{*p/=i*i;m*=i;i=2;}
		else i++;
	return m;
}
void print1(int a,int b,int sd,int *p,int original_delta)//无分数线时(a=1)输出
{
 		if (original_delta==0){printf("方程有两个相等的实数根\n");
 		    printf("x1=x2=%d\n",b);}
		else if(original_delta>0)
		{ printf("方程有两个不相等的实数根\n");
			if(sd==1)
			   	if((*p)==1)
				   if(b==0)	printf("x1=1\nx2=-1\n");
					else printf("x1=%d\nx2=%d\n",b+1,b-1);
				else
					if(b==0) printf("x1=√%d\nx2=-√%d\n",*p,*p);
					else printf("x1=%d+√%d\nx2=%d-√%d\n",b,*p,b,*p);
			else
				if((*p)==1)
				   if(b==0)	printf("x1=%d\nx2=-%d\n",sd,sd);
					else printf("x1=%d\nx2=%d\n",b+sd,b-sd);
				else
					if(b==0) printf("x1=%d√%d\nx2=-%d√%d\n",sd,*p,sd,*p);
					else printf("x1=%d+%d√%d\nx2=%d-%d√%d\n",b,sd,*p,b,sd,*p);}
		else { printf("方程有两个共轭的虚根\n");
	        if(sd==1)
			   	if((*p)==1)
				   if(b==0)	printf("x1=i\nx2=-i\n");
					else printf("x1=%d+i\nx2=%d-i\n",b,b);
				else
					if(b==0) printf("x1=√%di\nx2=-√%di\n",*p,*p);
					else printf("x1=%d+√%di\nx2=%d-√%di\n",b,*p,b,*p);
			else
				if((*p)==1)
				   if(b==0)	printf("x1=%di\nx2=-%di\n",sd,sd);
					else printf("x1=%d+%di\nx2=%d-%di\n",b,sd,b,sd);
				else
					if(b==0) printf("x1=%d√%di\nx2=-%d√%di\n",sd,*p,sd,*p);
					else printf("x1=%d+%d√%di\nx2=%d-%d√%di\n",b,sd,*p,b,sd,*p);}
}
void print2(int a,int b,int sd,int *p,int original_delta)//有分数线时(a>1)输出
{
	int i,sum1,sum2,a1;
	if(original_delta==0){printf("方程有两个相等的实数根\n");
	if(b>0) printf("       %d\nx1=x2=--------\n       %d\n",b,a);
	else printf("         %d\nx1=x2=- --------\n         %d\n",-b,a);}
	else if(original_delta>0){printf("方程有两个不相等的实数根\n");
		if(sd==1)
			if((*p)==1)
				if(b==0)printf("    1\nx1=--------\n    %d\n      1\nx2=- --------\n      %d\n",a,a);
				else{sum1=b+1;sum2=b-1;a1=a;
					for(i=2;i<=sum1||i<=a;)
					{if(sum1%i==0&&a%i==0){sum1/=i;a/=i;i=2;}else i++;}
					for(i=2;i<=sum2||i<=a1;)
					{if(sum2%i==0&&a1%i==0){sum2/=i;a1/=i;i=2;}else i++;}
					if(a==1)
						printf("x1=%d\n",sum1);
					else {if(sum1>0)printf("    %d\nx1=--------\n    %d\n",sum1,a);
					else printf("      %d\nx1=- --------\n      %d\n",-sum1,a);}
					if(a1==1)
						printf("x2=%d\n",sum2);
					else {if(sum2>0)printf("    %d\nx2=--------\n    %d\n",sum2,a1);
					else printf("      %d\nx2=- --------\n      %d\n",-sum2,a1);}
					}
			else
				if(b==0)printf("    √%d\nx1=--------\n      %d\n      √%d\nx2=- --------\n      %d\n",*p,a,*p,a);
				else printf("    %d+√%d\nx1=--------\n     %d\n     %d-√%d\nx2=--------\n     %d\n",b,*p,a,b,*p,a);
		else
			if((*p)==1)
				if(b==0)printf("    %d\nx1=--------\n    %d\n      %d\nx2=- --------\n      %d\n",sd,a,sd,a);
				else{sum1=b+sd;sum2=b-sd;a1=a;
					for(i=2;i<=sum1||i<=a;)
					{if(sum1%i==0&&a%i==0){sum1/=i;a/=i;i=2;}else i++;}
					for(i=2;i<=sum2||i<=a1;)
					{if(sum2%i==0&&a1%i==0){sum2/=i;a1/=i;i=2;}else i++;}
					if(a==1)
						printf("x1=%d\n",sum1);
					else {if(sum1>0)printf("    %d\nx1=--------\n    %d\n",sum1,a);
					else printf("      %d\nx1=- --------\n      %d\n",-sum1,a);}
					if(a1==1)
						printf("x2=%d\n",sum2);
					else {if(sum2>0)printf("    %d\nx2=--------\n    %d\n",sum2,a1);
					else printf("      %d\nx2=- --------\n      %d\n",-sum2,a1);}
				}
			else
				if(b==0) printf("    %d√%d\nx1=--------\n     %d\n       %d√%d\nx2=- --------\n       %d\n",sd,*p,a,sd,*p,a);
				else printf("    %d+%d√%d\nx1=--------\n     %d\n     %d-%d√%d\nx2=--------\n     %d\n",b,sd,*p,a,b,sd,*p,a);}
	else{ printf("方程有两个共轭的虚根\n");
	    if(sd==1)
			if((*p)==1)
				if(b==0)printf("    i\nx1=--------\n    %d\n      i\nx2=- --------\n      %d\n",a,a);
				else   printf("    %d+i\nx1=--------\n    %d\n    %d-i\nx2=--------\n    %d\n",b,a,b,a);
			else
				if(b==0)printf("    √%di\nx1=--------\n      %d\n      √%di\nx2=- --------\n      %d\n",*p,a,*p,a);
				else printf("    %d+√%di\nx1=--------\n     %d\n     %d-√%di\nx2=--------\n     %d\n",b,*p,a,b,*p,a);
		else
			if((*p)==1)
				if(b==0)printf("    %di\nx1=--------\n    %d\n      %di\nx2=- --------\n      %d\n",sd,a,sd,a);
				else printf("    %d+%di\nx1=--------\n    %d\n    %d-%di\nx2=--------\n    %d\n",b,sd,a,b,sd,a);
			else
				if(b==0) printf("    %d√%di\nx1=--------\n     %d\n       %d√%di\nx2=- --------\n       %d\n",sd,*p,a,sd,*p,a);
				else printf("    %d+%d√%di\nx1=--------\n     %d\n    %d-%d√%di\nx2=--------\n     %d\n",b,sd,*p,a,b,sd,*p,a);}
	
}
int main()
{
    double original_a,original_b,original_c;//original_a/b/c为a,b,c原先的值(可能为整数/小数)
	int a,b,c,i,sd,delta,original_delta;
	//a,b,c为化为整数(*10^n)后的值,sd为根号delta化简后提出来的整数(如:delta原为√20(化简后为2√5),则sd=2)
	int *p=&delta;
	//*p或变量delta可变,改变后为√delta化简后的根号内的数(如:delta原为√20(化简后为2√5),改变后delta=5)
	char ch='y';//判断符
	while(ch=='y'||ch=='Y'){
	printf("一元二次方程一般形式:ax2+bx+c=0(a≠0)\n输入a,b,c(整数或三位以内小数)的值:");
	scanf("%lf%lf%lf",&original_a,&original_b,&original_c);
	if((double)(int)original_a!=original_a||((double)(int)original_b!=original_b)||((double)(int)original_c!=original_c))
	 {a=original_a*1000;b=original_b*1000;c=original_c*1000;
		for(;a%10==0&&b%10==0&&c%10==0;a/=10,b/=10,c/=10); }//若a,b,c中有小数,则分别乘10的倍数使去掉小数点
  	else {a=original_a;b=original_b;c=original_c;}
	while (a==0&&b==0){
			puts("不是方程,请重新输入:");
			scanf("%lf%lf%lf",&original_a,&original_b,&original_c);
			if((double)(int)original_a!=original_a||((double)(int)original_b!=original_b)||((double)(int)original_c!=original_c))
	 {a=original_a*1000;b=original_b*1000;c=original_c*1000;
	 for(;a%10==0&&b%10==0&&c%10==0;a/=10,b/=10,c/=10);}//同上
	 else {a=original_a;b=original_b;c=original_c;}}
	if(a==0&&b!=0)//此时为一次方程
		printf("x=%.2lf\n",-(double)c/(double)b);
	else if(a!=0){
		if(a<0){a=-a;b=-b;c=-c;}//使结果分母不带负号
		printf("a=%d,b=%d,c=%d\n",a,b,c);
		delta=b*b-4*a*c;
		printf("delta=%d\n",delta);original_delta=delta;
		a*=2;b=-b;sd=simplify(p);//a,b变为求根公式中的2a,-b
		for(i=2;i<=a||i<=b||i<=sd;)//将结果约分
		{
			if(a%i==0&&b%i==0&&sd%i==0)
				{a/=i;b/=i;sd/=i;i=2;}
				else i++;}
		if(a==1)
			print1(a,b,sd,p,original_delta);//无分数线
		else
			print2(a,b,sd,p,original_delta);//有分数线
		if(original_delta>=0)printf("近似值:\nx1=%.3lf\nx2=%.3lf\n",(b+sd*sqrt(delta))/a,(b-sd*sqrt(delta))/a);
  		}//有实根时输出近似值
  		printf("是否继续?(Y/N)");
  		fflush(stdin);//清空缓冲区
  		ch=getchar();
  	}
  	return 0;
 }

求点赞
Logo

一站式 AI 云服务平台

更多推荐