/** * @author Along * @desc 一元三次方程,二次方程,和一次方程求解工具类 */ public class EquationCalculation { /* 计算一元三次方程最大实根 * 一元三次方程(ax3+bx2+cx+d=0)的盛金公式解题法 * 输入:参数a,b,c,d * 1):当A=B=0时,方程有一个三重实根; * 2):当Δ=B^2-4AC>0时,方程有一个实根和一对共轭虚根,只处理实根; * 3):当Δ=B^2-4AC=0时,方程有三个实根,其中有一个两重根; * 4):当Δ=B^2-4AC<0时,方程有三个不相等的实根。 * 返回 : 所有根中大于0的最大值,不存在大于0的值时方程无有效解或有误,返回异常 */ public static double solveCubic(double a, double b, double c, double d) throws ArithmeticException{ double t1=0,t2=0,t3=0; if (a != 0) { double A = b * b - 3 * a * c; // A=b*b-3ac double B = b * c - 9 * a * d; // B=bc-9ad double C = c * c - 3 * b * d; // C=c*c-3bd double D = B * B - 4 * A * C; // 判别式D=B*B-4*A*C if (A == 0 && B == 0) { //当A=B=0时,盛金公式1: t1=t2=t3=-b/(3a)=-c/b=-3d/c t1 = -c / b; t2 = t1; t3 = t1; }else{ if (D > 0) { /* * 当D=B^2-4AC>0时,盛金公式2:t1=(-b-(Y1)^(1/3)-(Y2)^(1/3))/(3a); * t2,t3=(-2b+(Y1)^(1/3)+(Y2)^(1/3))/(6a)±i3^(1/2)((Y1)^(1/3)-(Y2)^(1/3))/(6a), * 其中Y1,Y2=Ab+3a(-B±(B^2-4AC)^(1/2))/2, * 因i^2=-1,故t2和t3为虚根,忽略不使用 */ double Y1 = A * b + 3 * a * (-B + Math.sqrt(D)) / 2; double Y2 = A * b + 3 * a * (-B - Math.sqrt(D)) / 2; // Math.pow(a,b)使用时a不能为负数,分情况判断计算 if(Y1<0) { Y1=-Math.pow(Math.abs(Y1), 1.0 / 3); }else { Y1=Math.pow(Math.abs(Y1), 1.0 / 3); } if(Y2<0) { Y2=-Math.pow(Math.abs(Y2), 1.0 / 3); }else { Y2=Math.pow(Math.abs(Y2), 1.0 / 3); } double F =Y1 +Y2; t1 = (-b - F) / (3 * a); t2 = t1; t3 = t1; }else if (D == 0) { /* * 当D=B^2-4AC=0时,盛金公式3:t1=-b/a+K; t2=t3=-K/2, * 其中K=B/A,(A≠0)。 * 盛金定理:当D=0时,若B≠0,盛金公式3一定不存在A≤0的值,故不需要判断A是否等于0 * */ double K = B / A; t1 = -b / a + K; t2 = -K / 2; t3 = t2; }else{ /* * 当D=B^2-4AC<0时,盛金公式4: t1=(-b-2A^(1/2)cos(θ/3))/(3a); * t2,t3=(-b+A^(1/2)(cos(θ/3)±3^(1/2)sin(θ/3)))/(3a), * 其中θ=arccosT,T=(2Ab-3aB)/(2A^(3/2)),(A>0,-1<T<1)。 * 盛金定理:当D<0时,盛金公式4一定不存在A<=0的值,且一定不存在T<=-1或T>=1的值,故条件A>0和-1<T<1不需要判断 * */ double T = (2 * A * b - 3 * a * B) / (2 * Math.sqrt(A * A * A)); double q = Math.acos(T); double q3 = q / 3.0; t1 = (-b - 2 * Math.sqrt(A) * Math.cos(q3)) / (3 * a); t2 = (-b + Math.sqrt(A) * Math.cos(q3) - Math.sqrt(A) * Math.sqrt(3) * Math.sin(q3)) / (3 * a); t3 = (-b + Math.sqrt(A) * Math.cos(q3) + Math.sqrt(A) * Math.sqrt(3) * Math.sin(q3)) / (3 * a); } } //返回多个结果中大于0的最大值,若都小于0,则返回0 double jg[]={t1,t2,t3}; Arrays.sort(jg); if(jg[2] < 0){ //方程无大于等于0的有效实根,返回0 throw new ArithmeticException("方程无大于等于0的有效实根!"); }else{ return jg[2]; } }else{ //a=0时,为一元二次方程,调用一元二次方程求根函数 return solveQuadratic(b,c,d); } } /* 计算一元二次方程最大实根 * 一元三次方程(ax2+bx+c=0)的公式解题法 * 输入:参数a,b,c * 1):当Δ=b^2-4ac<0时,方程有无实根; * 2):当Δ=b^2-4ac=0时,方程有两个相同的根为-b/2a; * 3):当Δ=b^2-4ac<0时,方程有两个根为(-b±(b^2-4ac)^(1/2))/(2a)。 * 返回 : 所有根中大于0的最大值根,不存在大于0的值时方程无有效解或有误,返回异常 */ public static double solveQuadratic(double a,double b,double c) throws ArithmeticException{ double t1=0,t2=0; if(a!=0){ double A = b * b - 4 * a *c; if(A < 0){ //方程无实根,返回0 throw new ArithmeticException("方程无实根!"); }else if(A == 0){ t1=t2= -b/(2*a); }else{ t1= (-b + Math.pow(A, 1.0/2)) / (2 * a); t2= (-b - Math.pow(A, 1.0/2)) / (2 * a); } //返回多个结果中大于0的最大值,若都小于0,则返回0 double jg[]={t1,t2}; Arrays.sort(jg); if(jg[1] <= 0){ //方程无大于等于0的有效实根,返回0 throw new ArithmeticException("方程无大于等于0的有效实根!"); }else{ return jg[1]; } }else{ //一元一次方程 return solveLinear(b,c); } } /* 计算一元一次方程实根 * 一元一次方程(ax+b=0)的公式解题法 * 输入:参数a,b * 当a!=0,且b!=0时,x=-b/a; * 当b=0时,x=0; * 返回 : 大于0的实根,不存在大于0的值时方程无有效解或有误,返回异常 */ public static double solveLinear(double a,double b) throws ArithmeticException{ double t1=0; if(b == 0){ //方程等式无意义,返回0 throw new ArithmeticException("方程等式无意义!"); }else { if(a!=0){ t1=-b/a; if(t1 < 0){ //方程无大于等于0的有效实根,返回0 throw new ArithmeticException("方程无大于等于0的有效实根!"); }else{ return t1; } }else{ //a=0且b!=0,方程等式不成立,返回异常信息 throw new ArithmeticException("方程等式不成立!"); } } } }
Java解一元一次方程,一元二次方程,一元三次方程
最新推荐文章于 2022-10-20 16:11:13 发布