一元四次方程求根算法java
时间: 2025-09-09 12:16:31 AIGC 浏览: 2
一元四次方程的一般形式为 \(ax^{4}+bx^{3}+cx^{2}+dx + e = 0\),其中 \(a\neq0\)。可以通过费拉里法来求解一元四次方程的根。以下是使用 Java 实现一元四次方程求根算法的代码示例:
```java
import java.util.ArrayList;
import java.util.List;
public class QuarticEquationSolver {
// 求解一元四次方程 ax^4 + bx^3 + cx^2 + dx + e = 0
public static List<Complex> solveQuartic(double a, double b, double c, double d, double e) {
List<Complex> roots = new ArrayList<>();
// 先将方程化为 x^4 + px^3 + qx^2 + rx + s = 0 的形式
double p = b / a;
double q = c / a;
double r = d / a;
double s = e / a;
// 再通过换元法 x = y - p/4,将方程化为 y^4 + Ay^2 + By + C = 0 的形式
double A = q - 3 * p * p / 8;
double B = r - p * q / 2 + p * p * p / 8;
double C = s - p * r / 4 + p * p * q / 16 - 3 * p * p * p * p / 256;
if (B == 0) {
// 当 B = 0 时,方程变为 y^4 + Ay^2 + C = 0,这是一个关于 y^2 的二次方程
double[] quadraticRoots = solveQuadratic(1, A, C);
for (double root : quadraticRoots) {
if (root >= 0) {
double sqrtRoot = Math.sqrt(root);
roots.add(new Complex(sqrtRoot - p / 4, 0));
roots.add(new Complex(-sqrtRoot - p / 4, 0));
} else {
double sqrtNegRoot = Math.sqrt(-root);
roots.add(new Complex(-p / 4, sqrtNegRoot));
roots.add(new Complex(-p / 4, -sqrtNegRoot));
}
}
} else {
// 一般情况,使用费拉里法
// 先求解一个辅助三次方程
double[] cubicRoots = solveCubic(8, 8 * A, 2 * A * A - 8 * C, -B * B);
double z = cubicRoots[0];
double m = Math.sqrt(2 * z);
double k = (A + z - B / m) / 2;
double l = (A + z + B / m) / 2;
double[] quadraticRoots1 = solveQuadratic(1, m, k);
double[] quadraticRoots2 = solveQuadratic(1, -m, l);
for (double root : quadraticRoots1) {
roots.add(new Complex(root - p / 4, 0));
}
for (double root : quadraticRoots2) {
roots.add(new Complex(root - p / 4, 0));
}
}
return roots;
}
// 求解一元二次方程 ax^2 + bx + c = 0
public static double[] solveQuadratic(double a, double b, double c) {
double discriminant = b * b - 4 * a * c;
if (discriminant >= 0) {
double sqrtDiscriminant = Math.sqrt(discriminant);
double root1 = (-b + sqrtDiscriminant) / (2 * a);
double root2 = (-b - sqrtDiscriminant) / (2 * a);
return new double[]{root1, root2};
} else {
return new double[]{};
}
}
// 求解一元三次方程 ax^3 + bx^2 + cx + d = 0
public static double[] solveCubic(double a, double b, double c, double d) {
double[] roots = new double[3];
// 先将方程化为 x^3 + px^2 + qx + r = 0 的形式
double p = b / a;
double q = c / a;
double r = d / a;
// 再通过换元法 x = y - p/3,将方程化为 y^3 + Ay + B = 0 的形式
double A = q - p * p / 3;
double B = r - p * q / 3 + 2 * p * p * p / 27;
double Q = (3 * A - p * p) / 9;
double R = (9 * p * q - 27 * r - 2 * p * p * p) / 54;
double D = Q * Q * Q + R * R;
if (D > 0) {
double S = Math.cbrt(R + Math.sqrt(D));
double T = Math.cbrt(R - Math.sqrt(D));
roots[0] = S + T - p / 3;
roots[1] = roots[2] = Double.NaN;
} else if (D == 0) {
double S = Math.cbrt(R);
roots[0] = 2 * S - p / 3;
roots[1] = roots[2] = -S - p / 3;
} else {
double theta = Math.acos(R / Math.sqrt(-Q * Q * Q));
roots[0] = 2 * Math.sqrt(-Q) * Math.cos(theta / 3) - p / 3;
roots[1] = 2 * Math.sqrt(-Q) * Math.cos((theta + 2 * Math.PI) / 3) - p / 3;
roots[2] = 2 * Math.sqrt(-Q) * Math.cos((theta + 4 * Math.PI) / 3) - p / 3;
}
return roots;
}
// 复数类
static class Complex {
double real;
double imag;
public Complex(double real, double imag) {
this.real = real;
this.imag = imag;
}
@Override
public String toString() {
if (imag == 0) {
return String.valueOf(real);
} else if (imag > 0) {
return real + " + " + imag + "i";
} else {
return real + " - " + (-imag) + "i";
}
}
}
public static void main(String[] args) {
double a = 1;
double b = -2;
double c = -3;
double d = 4;
double e = -5;
List<Complex> roots = solveQuartic(a, b, c, d, e);
for (Complex root : roots) {
System.out.println("Root: " + root);
}
}
}
```
### 代码说明:
1. **`solveQuartic` 方法**:用于求解一元四次方程 \(ax^{4}+bx^{3}+cx^{2}+dx + e = 0\),通过一系列变换和辅助方程的求解,最终得到方程的根。
2. **`solveQuadratic` 方法**:用于求解一元二次方程 \(ax^{2}+bx + c = 0\),根据判别式的值返回方程的根。
3. **`solveCubic` 方法**:用于求解一元三次方程 \(ax^{3}+bx^{2}+cx + d = 0\),同样通过变换和判别式的计算得到方程的根。
4. **`Complex` 类**:用于表示复数,方便处理可能出现的复数根。
### 复杂度分析:
- **时间复杂度**:主要由求解三次方程和二次方程的操作决定,时间复杂度为 \(O(1)\)。
- **空间复杂度**:主要用于存储方程的根,空间复杂度为 \(O(1)\)。
### 注意事项:
- 该算法可能会受到浮点数精度的影响,对于某些特殊的方程,可能会得到不准确的结果。
- 代码中使用了复数类来处理可能出现的复数根,但在实际应用中,可能需要根据具体需求进行调整。
阅读全文
相关推荐




















