/相 发表于 2024-4-14 21:27:15

解方程工具equation.exe

高次方程求解,三次方程参考范盛金的公式,四次方程采用费拉里降次为两个二次方程,五次方程没有精确的求根公式,采用牛顿迭代法(利用导线逼近0点)进而降次为四次方程,再套用费拉里将次(包含复数解)。
EQUATION.EXE

摘要:
=============================================================================
这是一个专注解方程和方程组的简单工具,帮助那些想快速计算出结果的童鞋们。求解
结果精确到小数点后12位,且支持复根。
=============================================================================

用法:
-----------------------------------------------------------------------------
equation ||
-----------------------------------------------------------------------------
/H显示帮助信息
/O求解一元方程
/M求解多元方程组
/R求解单位复元根
-----------------------------------------------------------------------------

示例:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
equation /O3 0 5 -6 -9      //求解一元四次方程3x^4+0x^3+5x^2-6x-9=0
The solution of the equation 3x^4+0x^3+5x^2-6x-9=0 is:
┌────────────────────────┐
Imag   root: -0.252438186547+1.696390660707i
               -0.252438186547-1.696390660707i
Real   root:1.293411063722
               -0.788534690627
└────────────────────────┘

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
equation /R5                  //求解5次复元根 x^5-1=0
┌────────────────────────┐
      x[ 1]= 0.309016994375+0.951056516295i
      x[ 2]=-0.809016994375+0.587785252292i
      x[ 3]=-0.809016994375-0.587785252292i
      x[ 4]= 0.309016994375-0.951056516295i
      x[ 5]= 1.000000000000-0.000000000000i
└────────────────────────┘

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
equation /M                     //进入方程组模式

         ---Quit using "q"
      {2                      //此处输入方程组个数
      Equation coefficients:
      3 2 5                   //第一个方程式的系数
      6 9 1                   //第二个方程式的系数
      Solution of equations:
      ┌───────────────┐
          x= 2.866666793823
          x=-1.800000071526
      └───────────────┘
      {{q                     //输入q退出该模式

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

equation.c源码(采取POS开源协议,即发布的每个作品都开源):
/*    CONSOLE SOLVING EQUATION TOOLS, COPYRIGHT@2016~2018 BY HAPPY    EQUATION.EXE    VERSION 1.0*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>//定义帮助说明//////////////////////////////////////////////////////#define HELPINFORMATION "\SOLVING EQUATION TOOLS, COPYRIGHT@2016~2018 BY HAPPY, VERSION 1.0\n\-----------------------------------------------------------------\n\equation ||\n\-----------------------------------------------------------------\n\/HDisplays help information\n\/OSolves the univariate equation\n\/MSolving Systems of multivariable Equations\n\/RSolve the unit root\n\-----------------------------------------------------------------\n\12/03/2016\n"/////////////////////////////////////////////////////////////////////***************功能函数群***************/void equation_set(int n) {      int i, j, m, r, k=0, t, mark;    float a;    printf("Equation coefficients:\n");    r=n;      for(j=0; j<n; j++){         for(i=0; i<r+1; i++){               scanf("%f", &a);      }      if(a!=0){mark=j;}    }    //系数修正    for(j=0; j<n; j++){      if(a+a != 0){               for(i=0; i<r+1; i++){                   a += a;            }      }    }    if(r==n)   {         printf("Solution of equations:\n");      for(t=0; t<n-1; t++)            for(m=0; m<n; m++)                for(j=0; j<n; j++)                  if(j!=m)                         {                        float b= a/a;                        for(i=0; i<n+1; i++)                            a -= a*b;                                          }         for(j=0; j<n; j++)             {                  a /=a;                  a /=a;         }    }    printf("┌───────────────┐\n");    for(j=0; j<r; j++){         printf("   x[%d]=%15.12f\n", j, a);    }    printf("└───────────────┘\n");}void twice(double a, double b, double c){    double x1,x2,den=2*a,delt=b*b-4*a*c;    if(a==0){      if(b==0){            printf("Not a real equation");      }      else{            printf("Reduced to once equation\nReal   root: x=%.12lf",-c/b);      }    }    else{            if(delt>0){            x1=-b/den+sqrt(delt)/den;            x2=-b/den-sqrt(delt)/den;            printf("Real   root: %15.12lf\n               %15.12lf",x1,x2);      }      else if(delt==0){            printf("Double root: %15.12lf",-b/den);      }      else if(delt<0){            x1=sqrt(-delt)/den;            printf("Imag   root: %15.12lf+%.12lfi\n               %15.12lf-%.12lfi",-b/den,x1,-b/den,x1);      }    }}double thice(double a, double b, double c, double d, int gk){    double A=b*b-3*a*c,B=b*c-9*a*d,C=c*c-3*b*d,delta=B*B-4*A*C;    if(A==0 && B==0){      if(gk!=1){printf("Triple real: %15.12lf",-b/(3*a));}      return -b/(3*a);    }    else if(delta>0){      double Y1=A*b+3*a*(-B+sqrt(delta))/2.0,Y2=A*b+3*a*(-B-sqrt(delta))/2.0;      Y1=(Y1>0)? pow(Y1,1.0/3.0) :-pow(-Y1,1.0/3.0);      Y2=(Y2>0)? pow(Y2,1.0/3.0) :-pow(-Y2,1.0/3.0);      double x1=(-b-Y1-Y2)/(3.0*a);      double prr=(-2*b+Y1+Y2)/(6.0*a),pri=(Y1-Y2)*sqrt(3)/(6.0*a);      if(gk!=1){printf("Firstreal: %15.12lf\nImag   root: %15.12lf+%.12lfi\n               %15.12lf-%.12lfi",x1,prr,pri,prr,pri);}      return x1;    }    else if(delta==0){      if(gk!=1){printf("Double real: %15.12lf\n               Otherreal: %15.12lf\n",-B/(2.0*A),-b/a+B/A);}      if(-B/(2.0*A) > -b/a+B/A){            return -B/(2.0*A);      }else{            return -b/a+B/A;      }    }    else if(delta<0){      double r=acos((2*A*b-3*a*B)/(2*A*sqrt(A)));            double x1=(-b-2.0*sqrt(A)*cos(r/3.0))/(3.0*a);      double x2=(-b-2*sqrt(A)*cos((r+2*M_PI)/3.0))/(3.0*a);      double x3=(-b-2*sqrt(A)*cos((r+4*M_PI)/3.0))/(3.0*a);      if(gk!=1){printf("Triple real: %15.12lf\n               %15.12lf\n               %15.12lf",x1,x2,x3);}      double tempv;      if(x1 > x2){            tempv=x1;      }else{            tempv=x2;      }      if(tempv > x3){            return tempv;      }else{            return x3;      }    }}void foice(double a, double b, double c, double d, double e){    double y,f,M,N,P;    int i;    b/=a;c/=a;d/=a;e/=a;a=1;    f=8;    f=-4.0*c;    f=-(8.0*e-2.0*b*d);    f=-e*(b*b-4.0*c)-d*d;    y=thice(f,f,f,f,1);    M=sqrt(8.0*y+b*b-4.0*c);    N=b*y-d;    if(M==0){      P=sqrt(y*y-e);      twice(2.0,b,2.0*(y+P));      printf("\n");      twice(2.0,b,2.0*(y-P));    }else{      twice(2.0,b+M,2.0*(y+N/M));      printf("\n");      twice(2.0,b-M,2.0*(y-N/M));    }}void fifth(double a, double b, double c, double d, double e, double f){   double r,x,F,F1;   b/=a;c/=a;d/=a;e/=a;f/=a;   a=-1.0;    do    {            x=a;         F=x*x*x*x*x+b*x*x*x*x+c*x*x*x+d*x*x+e*x+f;         F1=5*x*x*x*x+4*b*x*x*x+3*c*x*x+2*d*x+e;         a=x-F/F1;      }    while(fabs(x-a)>=1e-10);    double e1=-f/x,d1=(e1-e)/x,c1=(d1-d)/x,b1=(c1-c)/x;   foice(1.0,b1,c1,d1,e1);    printf ("\nIterative: %15.12lf",x);}/***************业务函数群***************///字符串转等式char* atop(char *s){    if(atof(s)>=0){      char *r=malloc(strlen(s)+strlen("+")+1);      strcpy(r,"+");strcat(r,s);          return r;    }    return s;}//解多元方程组void Multivariable_Equations(){    char str;    puts("   ---Quit using "q"");    while(printf("{"),fgets(str,7,stdin)!=NULL){      char *i=strchr(str,'\n');      if(i!=NULL){*i='\0';}      if (i!=str){            if(!strcmp(str,"q")){break;}            equation_set(atoi(str));      }    }}//解一元高次方程void Univariate_Equation(int argc, char** argv){    if(argc==4){      printf("The solution of the equation %sx%s=0 is: \n",argv,atop(argv));      printf("┌────────────────────────┐\n");      if(atof(argv)==0){printf("Not a real equation");}else{printf("%15.12lf",-atof(argv)/atof(argv));}         printf("\n└────────────────────────┘");    }    else if(argc==5){      printf("The solution of the equation %sx^2%sx%s=0 is: \n",argv,atop(argv),atop(argv));      printf("┌────────────────────────┐\n");      twice(atof(argv),atof(argv),atof(argv));      printf("\n└────────────────────────┘");    }    else if(argc==6){      printf("The solution of the equation %sx^3%sx^2%sx%s=0 is: \n",argv,atop(argv),atop(argv),atop(argv));      printf("┌────────────────────────┐\n");      if(atof(argv)==0){            printf("Reduced to a quadratic equation\n");            twice(atof(argv),atof(argv),atof(argv));      }      else{            thice(atof(argv),atof(argv),atof(argv),atof(argv),0);      }      printf("\n└────────────────────────┘");    }    else if(argc==7){      printf("The solution of the equation %sx^4%sx^3%sx^2%sx%s=0 is: \n",argv,atop(argv),atop(argv),atop(argv),atop(argv));      printf("┌────────────────────────┐\n");      if(atof(argv)==0){            printf("Reduced to cubic equation\n");            if(atof(argv)==0){                printf("Reduced to a quadratic equation\n");                twice(atof(argv),atof(argv),atof(argv));            }else{                thice(atof(argv),atof(argv),atof(argv),atof(argv),0);            }      }      else{            foice(atof(argv),atof(argv),atof(argv),atof(argv),atof(argv));      }      printf("\n└────────────────────────┘");    }    else if(argc==8){      printf("The solution of the equation %sx^5%sx^4%sx^3%sx^2%sx%s=0 is: \n",argv,atop(argv),atop(argv),atop(argv),atop(argv),atop(argv));      printf("┌────────────────────────┐\n");      if(atof(argv)==0){            printf("Reduced to foice equation\n");            if(atof(argv)==0){                printf("Reduced to cubic equation\n");                if(atof(argv)==0){                  printf("Reduced to a quadratic equation\n");                  twice(atof(argv),atof(argv),atof(argv));                }else{                  thice(atof(argv),atof(argv),atof(argv),atof(argv),0);                }                            }else{                foice(atof(argv),atof(argv),atof(argv),atof(argv),atof(argv));            }      }else{            fifth(atof(argv),atof(argv),atof(argv),atof(argv),atof(argv),atof(argv));      }      printf("\n└────────────────────────┘");    }}//单位元根void Unit_Root(int argc, char** argv){    if(argc!=3){      printf("Missing parameters\n");                exit(1);      }    int i, n=atoi(argv);    printf("┌──────────────────────┐\n");    for(i=1; i<n; i++){      if(i==n){printf("   r[%2d]=%15.12lf%.12lfi",i,cos(2*i*M_PI/n),sin(2*i*M_PI/n));break;}      if(sin(2*i*M_PI/n)<0){            printf("   r[%2d]=%15.12lf%.12lfi\n",i,cos(2*i*M_PI/n),sin(2*i*M_PI/n));      }      else{            printf("   r[%2d]=%15.12lf+%.12lfi\n",i,cos(2*i*M_PI/n),sin(2*i*M_PI/n));      }      }    printf("   r[%2d]= 1.000000000000", n);    printf("\n└──────────────────────┘");}/*************MAIN主函数入口*************/int main(int argc, char** argv){    if( (argc >1) && (argv=='/') )    {      switch(argv)      {            case 'H':            case 'h':                fputs(HELPINFORMATION,stdout);                exit(0);            case 'M':            case 'm':                Multivariable_Equations();                break;            case 'O':            case 'o':                Univariate_Equation(argc, argv);                break;            case 'R':            case 'r':                Unit_Root(argc, argv);                break;            default:                fputs(HELPINFORMATION,stdout);                exit(1);      }      return 0;    }    fputs(HELPINFORMATION,stdout);    exit(1);}

inabilezami 发表于 2024-4-14 21:27:38

我win732位系统,运行你的程序一闪就没了!

gocehuzana 发表于 2024-4-14 21:28:29

命令行程序,跟之前的计算器用法一样。
在cmd窗口输入equation /O3 0 5 -6 -9
我的程序都是在一天之内写的,不可能有太多时间去写界面,所以都是命令行程序。就像你用的dir命令一样。
命令行具有启动快,速度快,内存占用小的优点。

opukidefugowu 发表于 2024-4-14 21:28:49

打开cmd窗口运行成功,用命令行输入对打字速度要求较高。

uliaxoxujiq 发表于 2024-4-14 21:29:23

没有啊,直接复制粘贴就能运行,连按键都不需要,命令行的好处就是直接复制粘贴。这些都是批处理算法流中的,都是可以用来批量无人值守,自动计算的,需要批处理或者lua语言的调用。

核心算法都在那了,只需要加个界面就能像你的计算器一样点击运行了,但是写界面我还得花1天时间,就暂时没界面,我现在正在开发自己的高精度算法库,所以时间比较紧。

asukrimukozor 发表于 2024-4-14 21:29:28

高精度算法库,反正切函数的迭代式会推导吗?我不会推导,用的方法速度较慢。
宝宝说:“反三角函数可以以三角函数为基础,使用牛顿迭代法求解。“,但是我不会,你数学很强,知道是怎么回事吗?

ocideeweguy 发表于 2024-4-14 21:30:13

赞!
比我牛逼
不过我一般都用mathematica解方程!

inabilezami 发表于 2024-4-14 21:30:54

mathematica虽好,但是mathematica也是程序啊。而且我发现mathematica在某些情况下给出的解是错误的。而且mathematica不免费。我用的还是旧版本。

afijozaci 发表于 2024-4-14 21:31:35

galois理论仅仅是根塔理论,而且他21岁就为了女人草率的去决斗而丢了性命。他的理论也如同他本人一样,只有在有根式解的前提下奏效。

而我的程序是数值解,就是用浮点复数去表示解,一个实系数高次方程可以没有根式解,但必须复数解。我只是用导线逼近下复数解而已,得出的结果都是浮点复数,而不是根式。所以我完全是用C语言程序设计的思想去做的。

即便是mathmatica也不可能给出复杂高次方程的根式解。

ucobiit 发表于 2024-4-14 21:32:31

我觉得先确定根的范围,
然后随机生成数,然后用牛顿迭代法求解方程
页: [1]
查看完整版本: 解方程工具equation.exe