【C语言】解一元二次方程完整版(保留根号,自动化简,完全按代数格式)
C语言解一元二次方程特点不同于大多数程序,结果可保留根号可输入小数,输入小数会自动通分成整数根式自动化简,系数是1会省略结果可输出虚数打开一次程序可计算多次解一个方程的流程输入a,b,c值a,b,c中若有小数便转为整数计算出**delta(Δ)**并化为最简二次根式计算出2a,-b的值并约分按照代数格式输出输出根的近似值要点函数 print1() 和函数print2()用来按代数格式输出此部分较为
·
C语言解一元二次方程
特点
- 不同于大多数程序,结果可保留根号
- 可输入小数,输入小数会自动通分成整数
- 根式自动化简,系数是1会省略
- 结果可输出虚数
- 打开一次程序可计算多次
解一个方程的流程
- 输入a,b,c值
- a,b,c中若有小数便转为整数
- 计算出delta并化为最简二次根式
- 计算出2a,-b的值并约分
- 按照代数格式输出
- 输出根的近似值
要点
- 函数
print1()和函数print2()用来按代数格式输出
- 此部分较为庞大,本人目前没想到简单的方法,若有大佬想到可在评论区提建议
- 函数
simplify()用来化简二次根式(Δ\sqrt{Δ}Δ) - 数学上原求根公式为x=−b±b2−4ac2ax=\frac{-b±\sqrt{b^2-4ac}}{2a}x=2a−b±b2−4ac,用本程序中的变量表示为x=b±sd∗pax=\frac{b±sd\sqrt{*p}}{a}x=ab±sd∗p或x=b±sddeltaax=\frac{b±sd\sqrt{delta}}{a}x=ab±sddelta
(a,b为变化后的2a,-b) main()函数10~13行的部分用来将小数利用等式的性质变为整数,再赋给a,b,c
效果
- 这里只放两张图,可以自己复制代码后尝试
- 注意:测试的清空缓冲区命令
fflush(stdin);在Termux这里不可用,电脑上测试(我用的dev-c++)时可用。因此这两张图上“是否继续”会直接跳过,在电脑上使用不会出问题

代码区(欢迎复制)
#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=δ
//*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;
}
求点赞
更多推荐




所有评论(0)