找回密码
 欢迎注册
查看: 11986|回复: 17

[原创] 解方程工具equation.exe

[复制链接]
发表于 2017-1-18 20:07:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

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

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

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

示例:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
equation /O  3 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 /R  5                  //求解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                     //进入方程组模式

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

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


equation.c源码(采取POS开源协议,即发布的每个作品都开源):
  1. /*
  2.     CONSOLE SOLVING EQUATION TOOLS, COPYRIGHT@2016~2018 BY HAPPY
  3.     EQUATION.EXE
  4.     VERSION 1.0
  5. */

  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <math.h>

  10. //定义帮助说明//////////////////////////////////////////////////////
  11. #define HELPINFORMATION "\
  12. SOLVING EQUATION TOOLS, COPYRIGHT@2016~2018 BY HAPPY, VERSION 1.0\n\
  13. -----------------------------------------------------------------\n\
  14. equation [/O {parameters}]|[/M]|[/R {parameters}]\n\
  15. -----------------------------------------------------------------\n\
  16.   /H  Displays help information\n\
  17.   /O  Solves the univariate equation\n\
  18.   /M  Solving Systems of multivariable Equations\n\
  19.   /R  Solve the unit root\n\
  20. -----------------------------------------------------------------\n\
  21. 12/03/2016\n"
  22. ////////////////////////////////////////////////////////////////////

  23. /***************功能函数群***************/
  24. void equation_set(int n)
  25. {  
  26.     int i, j, m, r, k=0, t, mark;
  27.     float a[11][12];
  28.     printf("Equation coefficients:\n");
  29.     r=n;  
  30.     for(j=0; j<n; j++){   
  31.         for(i=0; i<r+1; i++){   
  32.             scanf("%f", &a[j][i]);
  33.         }
  34.         if(a[j][0]!=0){mark=j;}
  35.     }
  36.     //系数修正
  37.     for(j=0; j<n; j++){
  38.         if(a[j][0]+a[mark][0] != 0){   
  39.             for(i=0; i<r+1; i++){   
  40.                 a[j][i] += a[mark][i];
  41.             }
  42.         }
  43.     }

  44.     if(r==n)
  45.     {   
  46.         printf("Solution of equations:\n");
  47.         for(t=0; t<n-1; t++)
  48.             for(m=0; m<n; m++)
  49.                 for(j=0; j<n; j++)
  50.                     if(j!=m)     
  51.                     {  
  52.                         float b= a[j][m]/a[m][m];
  53.                         for(i=0; i<n+1; i++)
  54.                             a[j][i] -= a[m][i]*b;                     
  55.                     }
  56.         for(j=0; j<n; j++)     
  57.         {   
  58.                 a[j][n] /=a[j][j];   
  59.                 a[j][j] /=a[j][j];
  60.         }
  61.     }
  62.     printf("┌───────────────┐\n");
  63.     for(j=0; j<r; j++){   
  64.         printf("   x[%d]=%15.12f\n", j, a[j][n]);
  65.     }
  66.     printf("└───────────────┘\n");
  67. }

  68. void twice(double a, double b, double c)
  69. {
  70.     double x1,x2,den=2*a,delt=b*b-4*a*c;
  71.     if(a==0){
  72.         if(b==0){
  73.             printf("  Not a real equation");
  74.         }
  75.         else{
  76.             printf("  Reduced to once equation\n  Real   root: x=%.12lf",-c/b);
  77.         }
  78.     }
  79.     else{   
  80.         if(delt>0){
  81.             x1=-b/den+sqrt(delt)/den;
  82.             x2=-b/den-sqrt(delt)/den;
  83.             printf("  Real   root: %15.12lf\n               %15.12lf",x1,x2);
  84.         }
  85.         else if(delt==0){
  86.             printf("  Double root: %15.12lf",-b/den);
  87.         }
  88.         else if(delt<0){
  89.             x1=sqrt(-delt)/den;
  90.             printf("  Imag   root: %15.12lf+%.12lfi\n               %15.12lf-%.12lfi",-b/den,x1,-b/den,x1);
  91.         }
  92.     }
  93. }

  94. double thice(double a, double b, double c, double d, int gk)
  95. {
  96.     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;
  97.     if(A==0 && B==0){
  98.         if(gk!=1){printf("  Triple real: %15.12lf",-b/(3*a));}
  99.         return -b/(3*a);
  100.     }
  101.     else if(delta>0){
  102.         double Y1=A*b+3*a*(-B+sqrt(delta))/2.0,Y2=A*b+3*a*(-B-sqrt(delta))/2.0;
  103.         Y1=(Y1>0)? pow(Y1,1.0/3.0) :-pow(-Y1,1.0/3.0);
  104.         Y2=(Y2>0)? pow(Y2,1.0/3.0) :-pow(-Y2,1.0/3.0);
  105.         double x1=(-b-Y1-Y2)/(3.0*a);
  106.         double prr=(-2*b+Y1+Y2)/(6.0*a),pri=(Y1-Y2)*sqrt(3)/(6.0*a);
  107.         if(gk!=1){printf("  First  real: %15.12lf\n  Imag   root: %15.12lf+%.12lfi\n               %15.12lf-%.12lfi",x1,prr,pri,prr,pri);}
  108.         return x1;
  109.     }
  110.     else if(delta==0){
  111.         if(gk!=1){printf("  Double real: %15.12lf\n               Other  real: %15.12lf\n",-B/(2.0*A),-b/a+B/A);}
  112.         if(-B/(2.0*A) > -b/a+B/A){
  113.             return -B/(2.0*A);
  114.         }else{
  115.             return -b/a+B/A;
  116.         }
  117.     }
  118.     else if(delta<0){
  119.         double r=acos((2*A*b-3*a*B)/(2*A*sqrt(A)));   
  120.         double x1=(-b-2.0*sqrt(A)*cos(r/3.0))/(3.0*a);
  121.         double x2=(-b-2*sqrt(A)*cos((r+2*M_PI)/3.0))/(3.0*a);
  122.         double x3=(-b-2*sqrt(A)*cos((r+4*M_PI)/3.0))/(3.0*a);
  123.         if(gk!=1){printf("  Triple real: %15.12lf\n               %15.12lf\n               %15.12lf",x1,x2,x3);}
  124.         double tempv;
  125.         if(x1 > x2){
  126.             tempv=x1;
  127.         }else{
  128.             tempv=x2;
  129.         }
  130.         if(tempv > x3){
  131.             return tempv;
  132.         }else{
  133.             return x3;
  134.         }
  135.     }
  136. }

  137. void foice(double a, double b, double c, double d, double e)
  138. {
  139.     double y,f[4],M,N,P;
  140.     int i;
  141.     b/=a;c/=a;d/=a;e/=a;a=1;
  142.     f[0]=8;
  143.     f[1]=-4.0*c;
  144.     f[2]=-(8.0*e-2.0*b*d);
  145.     f[3]=-e*(b*b-4.0*c)-d*d;
  146.     y=thice(f[0],f[1],f[2],f[3],1);
  147.     M=sqrt(8.0*y+b*b-4.0*c);
  148.     N=b*y-d;
  149.     if(M==0){
  150.         P=sqrt(y*y-e);
  151.         twice(2.0,b,2.0*(y+P));
  152.         printf("\n");
  153.         twice(2.0,b,2.0*(y-P));
  154.     }else{
  155.         twice(2.0,b+M,2.0*(y+N/M));
  156.         printf("\n");
  157.         twice(2.0,b-M,2.0*(y-N/M));
  158.     }
  159. }

  160. void fifth(double a, double b, double c, double d, double e, double f)
  161. {
  162.      double r,x,F,F1;
  163.      b/=a;c/=a;d/=a;e/=a;f/=a;
  164.      a=-1.0;
  165.     do
  166.     {
  167.            x=a;
  168.            F=x*x*x*x*x+b*x*x*x*x+c*x*x*x+d*x*x+e*x+f;
  169.            F1=5*x*x*x*x+4*b*x*x*x+3*c*x*x+2*d*x+e;
  170.            a=x-F/F1;   
  171.     }
  172.     while(fabs(x-a)>=1e-10);
  173.     double e1=-f/x,d1=(e1-e)/x,c1=(d1-d)/x,b1=(c1-c)/x;
  174.     foice(1.0,b1,c1,d1,e1);
  175.     printf ("\n  Iterative  : %15.12lf",x);
  176. }

  177. /***************业务函数群***************/
  178. //字符串转等式
  179. char* atop(char *s)
  180. {
  181.     if(atof(s)>=0){
  182.         char *r=malloc(strlen(s)+strlen("+")+1);
  183.         strcpy(r,"+");strcat(r,s);  
  184.         return r;
  185.     }
  186.     return s;
  187. }
  188. //解多元方程组
  189. void Multivariable_Equations()
  190. {
  191.     char str[8];
  192.     puts("[Multivariable Equations]   ---Quit using "q"");
  193.     while(printf("{"),fgets(str,7,stdin)!=NULL){
  194.         char *i=strchr(str,'\n');
  195.         if(i!=NULL){*i='\0';}
  196.         if (i!=str){
  197.             if(!strcmp(str,"q")){break;}
  198.             equation_set(atoi(str));
  199.         }
  200.     }
  201. }
  202. //解一元高次方程
  203. void Univariate_Equation(int argc, char** argv)
  204. {
  205.     if(argc==4){
  206.         printf("The solution of the equation %sx%s=0 is: \n",argv[2],atop(argv[3]));
  207.         printf("┌────────────────────────┐\n");
  208.         if(atof(argv[2])==0){printf("  Not a real equation");}else{printf("  %15.12lf",-atof(argv[3])/atof(argv[2]));}
  209.         printf("\n└────────────────────────┘");
  210.     }
  211.     else if(argc==5){
  212.         printf("The solution of the equation %sx^2%sx%s=0 is: \n",argv[2],atop(argv[3]),atop(argv[4]));
  213.         printf("┌────────────────────────┐\n");
  214.         twice(atof(argv[2]),atof(argv[3]),atof(argv[4]));
  215.         printf("\n└────────────────────────┘");
  216.     }
  217.     else if(argc==6){
  218.         printf("The solution of the equation %sx^3%sx^2%sx%s=0 is: \n",argv[2],atop(argv[3]),atop(argv[4]),atop(argv[5]));
  219.         printf("┌────────────────────────┐\n");
  220.         if(atof(argv[2])==0){
  221.             printf("  Reduced to a quadratic equation\n");
  222.             twice(atof(argv[3]),atof(argv[4]),atof(argv[5]));
  223.         }
  224.         else{
  225.             thice(atof(argv[2]),atof(argv[3]),atof(argv[4]),atof(argv[5]),0);
  226.         }
  227.         printf("\n└────────────────────────┘");
  228.     }
  229.     else if(argc==7){
  230.         printf("The solution of the equation %sx^4%sx^3%sx^2%sx%s=0 is: \n",argv[2],atop(argv[3]),atop(argv[4]),atop(argv[5]),atop(argv[6]));
  231.         printf("┌────────────────────────┐\n");
  232.         if(atof(argv[2])==0){
  233.             printf("  Reduced to cubic equation\n");
  234.             if(atof(argv[3])==0){
  235.                 printf("  Reduced to a quadratic equation\n");
  236.                 twice(atof(argv[4]),atof(argv[5]),atof(argv[6]));
  237.             }else{
  238.                 thice(atof(argv[3]),atof(argv[4]),atof(argv[5]),atof(argv[6]),0);
  239.             }
  240.         }
  241.         else{
  242.             foice(atof(argv[2]),atof(argv[3]),atof(argv[4]),atof(argv[5]),atof(argv[6]));
  243.         }
  244.         printf("\n└────────────────────────┘");
  245.     }
  246.     else if(argc==8){
  247.         printf("The solution of the equation %sx^5%sx^4%sx^3%sx^2%sx%s=0 is: \n",argv[2],atop(argv[3]),atop(argv[4]),atop(argv[5]),atop(argv[6]),atop(argv[7]));
  248.         printf("┌────────────────────────┐\n");
  249.         if(atof(argv[2])==0){
  250.             printf("  Reduced to foice equation\n");
  251.             if(atof(argv[3])==0){
  252.                 printf("  Reduced to cubic equation\n");
  253.                 if(atof(argv[4])==0){
  254.                     printf("  Reduced to a quadratic equation\n");
  255.                     twice(atof(argv[5]),atof(argv[6]),atof(argv[7]));
  256.                 }else{
  257.                     thice(atof(argv[4]),atof(argv[5]),atof(argv[6]),atof(argv[7]),0);
  258.                 }
  259.                
  260.             }else{
  261.                 foice(atof(argv[3]),atof(argv[4]),atof(argv[5]),atof(argv[6]),atof(argv[7]));
  262.             }
  263.         }else{
  264.             fifth(atof(argv[2]),atof(argv[3]),atof(argv[4]),atof(argv[5]),atof(argv[6]),atof(argv[7]));
  265.         }
  266.         printf("\n└────────────────────────┘");
  267.     }

  268. }
  269. //单位元根
  270. void Unit_Root(int argc, char** argv)
  271. {
  272.     if(argc!=3){
  273.         printf("Missing parameters\n");
  274.                 exit(1);
  275.         }
  276.     int i, n=atoi(argv[2]);
  277.     printf("┌──────────────────────┐\n");
  278.     for(i=1; i<n; i++){
  279.         if(i==n){printf("     r[%2d]=%15.12lf%.12lfi",i,cos(2*i*M_PI/n),sin(2*i*M_PI/n));break;}
  280.         if(sin(2*i*M_PI/n)<0){
  281.             printf("     r[%2d]=%15.12lf%.12lfi\n",i,cos(2*i*M_PI/n),sin(2*i*M_PI/n));
  282.         }
  283.         else{
  284.             printf("     r[%2d]=%15.12lf+%.12lfi\n",i,cos(2*i*M_PI/n),sin(2*i*M_PI/n));
  285.         }   
  286.     }
  287.     printf("     r[%2d]= 1.000000000000", n);
  288.     printf("\n└──────────────────────┘");
  289. }

  290. /*************MAIN主函数入口*************/
  291. int main(int argc, char** argv)
  292. {
  293.     if( (argc >1) && (argv[1][0]=='/') )
  294.     {
  295.         switch(argv[1][1])
  296.         {
  297.             case 'H':
  298.             case 'h':
  299.                 fputs(HELPINFORMATION,stdout);
  300.                 exit(0);

  301.             case 'M':
  302.             case 'm':
  303.                 Multivariable_Equations();
  304.                 break;

  305.             case 'O':
  306.             case 'o':
  307.                 Univariate_Equation(argc, argv);
  308.                 break;

  309.             case 'R':
  310.             case 'r':
  311.                 Unit_Root(argc, argv);
  312.                 break;

  313.             default:
  314.                 fputs(HELPINFORMATION,stdout);
  315.                 exit(1);
  316.         }
  317.         return 0;

  318.     }
  319.     fputs(HELPINFORMATION,stdout);
  320.     exit(1);
  321. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2017-1-18 20:42:16 | 显示全部楼层
我win732位系统,运行你的程序一闪就没了!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2017-1-18 20:57:01 | 显示全部楼层
落叶 发表于 2017-1-18 20:42
我win732位系统,运行你的程序一闪就没了!

命令行程序,跟之前的计算器用法一样。
在cmd窗口输入equation /O  3 0 5 -6 -9
我的程序都是在一天之内写的,不可能有太多时间去写界面,所以都是命令行程序。就像你用的dir命令一样。
命令行具有启动快,速度快,内存占用小的优点。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2017-1-18 21:06:47 | 显示全部楼层
打开cmd窗口运行成功,用命令行输入对打字速度要求较高。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2017-1-18 21:22:06 | 显示全部楼层
落叶 发表于 2017-1-18 21:06
打开cmd窗口运行成功,用命令行输入对打字速度要求较高。


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

核心算法都在那了,只需要加个界面就能像你的计算器一样点击运行了,但是写界面我还得花1天时间,就暂时没界面,我现在正在开发自己的高精度算法库,所以时间比较紧。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2017-1-18 21:31:11 | 显示全部楼层
高精度算法库,反正切函数的迭代式会推导吗?我不会推导,用的方法速度较慢。
宝宝说:“反三角函数可以以三角函数为基础,使用牛顿迭代法求解。“,但是我不会,你数学很强,知道是怎么回事吗?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2017-1-19 09:01:45 | 显示全部楼层
赞!
比我牛逼
不过我一般都用mathematica解方程!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2017-1-19 12:55:58 | 显示全部楼层
mathematica 发表于 2017-1-19 09:01
赞!
比我牛逼
不过我一般都用mathematica解方程!

mathematica虽好,但是mathematica也是程序啊。而且我发现mathematica在某些情况下给出的解是错误的。而且mathematica不免费。我用的还是旧版本。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2017-1-19 13:08:05 | 显示全部楼层
math_humanbeing 发表于 2017-1-19 09:08
我突然想到一个问题,解高次方程可以用galois理论,那么求解过程到底能不能机械化?

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

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

即便是mathmatica也不可能给出复杂高次方程的根式解。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2017-3-20 12:08:36 | 显示全部楼层
我觉得先确定根的范围,
然后随机生成数,然后用牛顿迭代法求解方程
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-3-28 19:46 , Processed in 0.055448 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表