复数在数学、科学或者工程领域是很常用的,可以通过调用Apache Commons Math库来完成,也可以自己手撸。
一、使用Apache Commons Math库
这个库有多个版本,在写这篇文章时,它的最新版是2022年12月19日的4.0-beta1,构建坐标是org.apache.commons:commons-math4-core:4.0-beta1,考虑到程序稳定性,我们可以使用目前开发者用得最多的版本3.6.1(2016年3月17日发布),Maven依赖如下:
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-math3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
示例代码如下:
import org.apache.commons.math3.complex.Complex;
public class ACMComplexDemo {
public static void main(String[] args) {
Complex c = new Complex(3, 5);
Complex d = new Complex(2, -2);
System.out.println(c);
System.out.println("c = " + c.getReal() + " + " + c.getImaginary() + "i");
System.out.println(c + " * " + d + " = " + c.multiply(d));
System.out.println(c + " / " + d + " = " + c.divide(d));
}
}
二、自己开发一个复数类
public class SimpleComplex {
private double real;
private double imaginary;
// 无参构造
public SimpleComplex() {
this(0.0, 0.0);
}
// 双参构造,用于表示虚数
public SimpleComplex(double real, double imaginary) {
this.real = real;
this.imaginary = imaginary;
}
// 单参构造,适用于实数范围
public SimpleComplex(double real) {
this(real, 0.0);
}
// 加法
public SimpleComplex add(SimpleComplex other) {
double real = this.real + other.real;
double imaginary = this.real + other.imaginary;
return new SimpleComplex(real, imaginary);
}
// 减法
public SimpleComplex sub(SimpleComplex other) {
return this.add(opposite(other));
}
// 乘法
public SimpleComplex mul(SimpleComplex other) {
double real = this.real * other.real - this.imaginary * other.imaginary;
double imaginary = this.real * other.imaginary + this.imaginary * other.real;
return new SimpleComplex(real, imaginary);
}
// 除法
public SimpleComplex div(SimpleComplex other) {
double real = (this.real * other.real + this.imaginary * other.imaginary)
/ (other.real * other.real + other.imaginary * other.imaginary);
double imaginary = (this.imaginary * other.real - this.real * other.imaginary)
/ (other.real * other.real + other.imaginary * other.imaginary);
return new SimpleComplex(real, imaginary);
}
// 获取实部
public double getReal() {
return real;
}
// 获取虚部
public double getImaginary() {
return imaginary;
}
@Override
public String toString() {
if (this.real == 0.0) {
return this.imaginary + "i";
} else if (this.imaginary == 0.0) {
return this.real + "";
} else if (this.imaginary < 0.0 && this.real != 0.0) {
return this.real + "" + this.imaginary + "i";
} else if (this.imaginary == 0.0 && this.real == 0.0) {
return "0.0";
}
return this.real + "+" + this.imaginary + "i";
}
// 判断两个复数是否相等
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
} else if (obj == null || !(obj instanceof SimpleComplex)) {
return false;
}
SimpleComplex tmp = (SimpleComplex) obj;
return Math.abs(this.real - tmp.real) < 1e-6
&& Math.abs(this.imaginary - tmp.imaginary) < 1e-6;
}
// 返回相反数
private static SimpleComplex opposite(SimpleComplex one) {
return new SimpleComplex(-one.real, -one.imaginary);
}
public static void main(String[] args) {
// 示例用法
SimpleComplex c1 = new SimpleComplex(3, 5); // 3 + 5i
SimpleComplex c2 = new SimpleComplex(2, -2); // 2 - 2i
System.out.println("c1 + c2 = " + c1.add(c2));
System.out.println("c1 - c2 = " + c1.sub(c2));
System.out.println("c1 * c2 = " + c1.mul(c2));
System.out.println("c1 / c2 = " + c1.div(c2));
}
}
显然,自己开发一个并不如Apache Commons Math做得好了,毕竟Apache的库提供了大量的运算方法,且逻辑严谨,是应用开发的首选。但执行一些简单的运算,譬如复数除法,在一定量的基础上,简单实现有一点点的性能优势。