in commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java [889:953]
private static Complex multiply(double re1, double im1, double re2, double im2) {
double a = re1;
double b = im1;
double c = re2;
double d = im2;
final double ac = a * c;
final double bd = b * d;
final double ad = a * d;
final double bc = b * c;
double x = ac - bd;
double y = ad + bc;
// --------------
// NaN can occur if:
// - any of (a,b,c,d) are NaN (for NaN or Infinite complex numbers)
// - a multiplication of infinity by zero (ac,bd,ad,bc).
// - a subtraction of infinity from infinity (e.g. ac - bd)
// Note that (ac,bd,ad,bc) can be infinite due to overflow.
//
// Detect a NaN result and perform correction.
//
// Modification from the listing in ISO C99 G.5.1 (6)
// Do not correct infinity multiplied by zero. This is left as NaN.
// --------------
if (Double.isNaN(x) && Double.isNaN(y)) {
// Recover infinities that computed as NaN+iNaN ...
boolean recalc = false;
if ((Double.isInfinite(a) || Double.isInfinite(b)) &&
isNotZero(c, d)) {
// This complex is infinite.
// "Box" the infinity and change NaNs in the other factor to 0.
a = boxInfinity(a);
b = boxInfinity(b);
c = changeNaNtoZero(c);
d = changeNaNtoZero(d);
recalc = true;
}
if ((Double.isInfinite(c) || Double.isInfinite(d)) &&
isNotZero(a, b)) {
// The other complex is infinite.
// "Box" the infinity and change NaNs in the other factor to 0.
c = boxInfinity(c);
d = boxInfinity(d);
a = changeNaNtoZero(a);
b = changeNaNtoZero(b);
recalc = true;
}
if (!recalc && (Double.isInfinite(ac) || Double.isInfinite(bd) ||
Double.isInfinite(ad) || Double.isInfinite(bc))) {
// The result overflowed to infinity.
// Recover infinities from overflow by changing NaNs to 0 ...
a = changeNaNtoZero(a);
b = changeNaNtoZero(b);
c = changeNaNtoZero(c);
d = changeNaNtoZero(d);
recalc = true;
}
if (recalc) {
x = Double.POSITIVE_INFINITY * (a * c - b * d);
y = Double.POSITIVE_INFINITY * (a * d + b * c);
}
}
return new Complex(x, y);
}