Complex division by zero:
 z / 0 = INF if z is not ZERO
 0 / 0 = NaN


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1164756 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Gilles Sadowski 2011-09-02 23:05:01 +00:00
parent 6a895ec220
commit 32b0f7336b
2 changed files with 30 additions and 9 deletions

View File

@ -78,6 +78,8 @@ public class Complex implements FieldElement<Complex>, Serializable {
private final transient boolean isNaN;
/** Record whether this complex number is infinite. */
private final transient boolean isInfinite;
/** Record whether this complex number is zero. */
private final transient boolean isZero;
/**
* Create a complex number given only the real part.
@ -101,6 +103,7 @@ public class Complex implements FieldElement<Complex>, Serializable {
isNaN = Double.isNaN(real) || Double.isNaN(imaginary);
isInfinite = !isNaN &&
(Double.isInfinite(real) || Double.isInfinite(imaginary));
isZero = real == 0 && imaginary == 0;
}
/**
@ -222,7 +225,10 @@ public class Complex implements FieldElement<Complex>, Serializable {
* <li>If either {@code this} or {@code divisor} has a {@code NaN} value
* in either part, {@link #NaN} is returned.
* </li>
* <li>If {@code divisor} equals {@link #ZERO}, {@link #NaN} is returned.
* <li>If {@code this} and {@code divisor} are both {@link #ZERO},
* {@link #NaN} is returned.
* </li>
* <li>If {@code divisor} equals {@link #ZERO}, {@link #INF} is returned.
* </li>
* <li>If {@code this} and {@code divisor} are both infinite,
* {@link #NaN} is returned.
@ -249,16 +255,17 @@ public class Complex implements FieldElement<Complex>, Serializable {
return NaN;
}
final double c = divisor.getReal();
final double d = divisor.getImaginary();
if (c == 0.0 && d == 0.0) {
return NaN;
if (divisor.isZero) {
return isZero ? NaN : INF;
}
if (divisor.isInfinite() && !isInfinite()) {
return ZERO;
}
final double c = divisor.getReal();
final double d = divisor.getImaginary();
if (FastMath.abs(c) < FastMath.abs(d)) {
double q = c / d;
double denominator = c * q + d;
@ -285,7 +292,7 @@ public class Complex implements FieldElement<Complex>, Serializable {
return NaN;
}
if (divisor == 0d) {
return NaN;
return isZero ? NaN : INF;
}
if (Double.isInfinite(divisor)) {
return !isInfinite() ? ZERO : NaN;

View File

@ -229,6 +229,13 @@ public class ComplexTest {
public void testDivideZero() {
Complex x = new Complex(3.0, 4.0);
Complex z = x.divide(Complex.ZERO);
Assert.assertEquals(z, Complex.INF);
}
@Test
public void testDivideZeroZero() {
Complex x = new Complex(0.0, 0.0);
Complex z = x.divide(Complex.ZERO);
Assert.assertEquals(z, Complex.NaN);
}
@ -349,13 +356,13 @@ public class ComplexTest {
@Test
public void testScalarMultiplyInf() {
Complex x = new Complex(1,1);
Complex x = new Complex(1, 1);
double yDouble = Double.POSITIVE_INFINITY;
Complex yComplex = new Complex(yDouble);
Assert.assertEquals(x.multiply(yComplex), x.multiply(yDouble));
yDouble = Double.NEGATIVE_INFINITY;
yComplex = new Complex(yDouble);
yComplex = new Complex(yDouble);
Assert.assertEquals(x.multiply(yComplex), x.multiply(yDouble));
}
@ -564,10 +571,17 @@ public class ComplexTest {
TestUtils.assertSame(Complex.NaN, negInfNegInf.atan());
}
@Test
public void testAtanI() {
for (int i = -10; i < 10; i++) {
System.out.println(new Complex(0, 1 - 0.1 * i).atan());
}
Assert.assertTrue(Complex.I.atan().isInfinite());
}
@Test
public void testAtanNaN() {
Assert.assertTrue(Complex.NaN.atan().isNaN());
Assert.assertTrue(Complex.I.atan().isNaN());
}
@Test