Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Số phức (Complex Numbers) trong Java – Triển khai và phép toán

Java không có kiểu số phức built-in. Cần tự triển khai class hoặc dùng thư viện (Apache Commons Math, JScience). Dưới đây là triển khai cơ bản và đầy đủ.

Triển khai class Complex cơ bản

public final class Complex {
    private final double real;
    private final double imag;
    
    public Complex(double real, double imag) {
        this.real = real;
        this.imag = imag;
    }
    
    // Factory methods
    public static Complex of(double real, double imag) { return new Complex(real, imag); }
    public static Complex ofReal(double real) { return new Complex(real, 0); }
    public static Complex ofImaginary(double imag) { return new Complex(0, imag); }
    public static Complex ZERO = new Complex(0, 0);
    public static Complex ONE = new Complex(1, 0);
    public static Complex I = new Complex(0, 1);
    
    // Getters
    public double getReal() { return real; }
    public double getImag() { return imag; }
    public double modulus() { return Math.hypot(real, imag); } // |z| = sqrt(re^2 + im^2)
    public double argument() { return Math.atan2(imag, real); } // Góc phase
    
    // Phép toán cơ bản (immutable – trả về instance mới)
    public Complex add(Complex other) {
        return new Complex(this.real + other.real, this.imag + other.imag);
    }
    
    public Complex subtract(Complex other) {
        return new Complex(this.real - other.real, this.imag - other.imag);
    }
    
    public Complex multiply(Complex other) {
        // (a+bi)(c+di) = (ac-bd) + (ad+bc)i
        double re = this.real * other.real - this.imag * other.imag;
        double im = this.real * other.imag + this.imag * other.real;
        return new Complex(re, im);
    }
    
    public Complex divide(Complex other) {
        // (a+bi)/(c+di) = [(ac+bd) + (bc-ad)i] / (c^2+d^2)
        double denom = other.real * other.real + other.imag * other.imag;
        if (denom == 0) throw new ArithmeticException("Division by zero");
        double re = (this.real * other.real + this.imag * other.imag) / denom;
        double im = (this.imag * other.real - this.real * other.imag) / denom;
        return new Complex(re, im);
    }
    
    public Complex conjugate() {
        return new Complex(real, -imag);
    }
    
    public Complex negate() {
        return new Complex(-real, -imag);
    }
    
    // Override Object methods
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Complex)) return false;
        Complex that = (Complex) o;
        return Double.compare(that.real, real) == 0 && Double.compare(that.imag, imag) == 0;
    }
    
    @Override
    public int hashCode() {
        return java.util.Objects.hash(real, imag);
    }
    
    @Override
    public String toString() {
        if (imag >= 0) return String.format("%.2f + %.2fi", real, imag);
        else return String.format("%.2f - %.2fi", real, -imag);
    }
    
    // Static operations (fluent)
    public static Complex add(Complex a, Complex b) { return a.add(b); }
    public static Complex multiply(Complex a, Complex b) { return a.multiply(b); }
    // ...
}

Ví dụ sử dụng

public class ComplexDemo {
    public static void main(String[] args) {
        Complex z1 = Complex.of(76.8, 24.0);
        Complex z2 = Complex.of(65.9, 11.23);
        
        Complex sum = z1.add(z2);
        Complex diff = z1.subtract(z2);
        Complex prod = z1.multiply(z2);
        Complex quot = z1.divide(z2);
        
        System.out.println("z1 = " + z1);           // 76.80 + 24.00i
        System.out.println("z2 = " + z2);           // 65.90 + 11.23i
        System.out.println("Sum = " + sum);         // 142.70 + 35.23i
        System.out.println("Diff = " + diff);       // 10.90 + 12.77i
        System.out.println("Product = " + prod);    // 4791.12 + 2451.12i
        System.out.println("Quotient = " + quot);   // 1.18 + 0.12i
        System.out.println("|z1| = " + z1.modulus()); // 80.52
        System.out.println("arg(z1) = " + Math.toDegrees(z1.argument()) + "°"); // 17.36°
    }
}

Thư viện chuyên nghiệp (Production)

  • Apache Commons Math: org.apache.commons.math4.complex.Complex – đầy đủ, tối ưu, tested.
  • JScience: org.jscience.mathematics.complex.Complex – hỗ trợ unit, symbolic.
  • Mặt khác: Nd4j, Hipparchus (fork Commons Math).


    org.apache.commons
    commons-math4
    4.4

Lưu ý

  • Immutable design (final fields, trả về instance mới) – an toàn, thread-safe, functional style.
  • Sử dụng Math.hypot cho modulus – tránh overflow/underflow so với Math.sqrt(re*re + im*im).
  • atan2 cho argument – xử lý đúng quadrant.
  • Equals/hashCode dựa trên double – cân nhắc epsilon cho floating point comparison nếu cần.