Introduced tests to guard against overflow (MATH-722). Corrected Javadoc and updated unit tests accordingly.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1236548 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sebastien Brisard 2012-01-27 07:00:19 +00:00
parent 7dc0c33e7c
commit 95d15eff45
2 changed files with 40 additions and 15 deletions

View File

@ -993,8 +993,8 @@ public class Complex implements FieldElement<Complex>, Serializable {
* </code>
* </pre>
* where the (real) functions on the right-hand side are
* {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
* {@link FastMath#cosh} and {@link FastMath#sinh}.
* {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and
* {@link FastMath#sinh}.
* <br/>
* Returns {@link Complex#NaN} if either real or imaginary part of the
* input argument is {@code NaN}.
@ -1004,8 +1004,8 @@ public class Complex implements FieldElement<Complex>, Serializable {
* <pre>
* Examples:
* <code>
* tan(1 &plusmn; INFINITY i) = 0 + NaN i
* tan(&plusmn;INFINITY + i) = NaN + NaN i
* tan(a &plusmn; INFINITY i) = 0 &plusmn; i
* tan(&plusmn;INFINITY + bi) = NaN + NaN i
* tan(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
* tan(&plusmn;&pi;/2 + 0 i) = &plusmn;INFINITY + NaN i
* </code>
@ -1015,9 +1015,15 @@ public class Complex implements FieldElement<Complex>, Serializable {
* @since 1.2
*/
public Complex tan() {
if (isNaN) {
if (isNaN || Double.isInfinite(real)) {
return NaN;
}
if (imaginary > 20.0) {
return createComplex(0.0, 1.0);
}
if (imaginary < -20.0) {
return createComplex(0.0, -1.0);
}
double real2 = 2.0 * real;
double imaginary2 = 2.0 * imaginary;
@ -1038,8 +1044,8 @@ public class Complex implements FieldElement<Complex>, Serializable {
* </code>
* </pre>
* where the (real) functions on the right-hand side are
* {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
* {@link FastMath#cosh} and {@link FastMath#sinh}.
* {@link FastMath#sin}, {@link FastMath#cos}, {@link FastMath#cosh} and
* {@link FastMath#sinh}.
* <br/>
* Returns {@link Complex#NaN} if either real or imaginary part of the
* input argument is {@code NaN}.
@ -1049,8 +1055,8 @@ public class Complex implements FieldElement<Complex>, Serializable {
* <pre>
* Examples:
* <code>
* tanh(1 &plusmn; INFINITY i) = NaN + NaN i
* tanh(&plusmn;INFINITY + i) = NaN + 0 i
* tanh(a &plusmn; INFINITY i) = NaN + NaN i
* tanh(&plusmn;INFINITY + bi) = &plusmn;1 + 0 i
* tanh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
* tanh(0 + (&pi;/2)i) = NaN + INFINITY i
* </code>
@ -1060,10 +1066,15 @@ public class Complex implements FieldElement<Complex>, Serializable {
* @since 1.2
*/
public Complex tanh() {
if (isNaN) {
if (isNaN || Double.isInfinite(imaginary)) {
return NaN;
}
if (real > 20.0) {
return createComplex(1.0, 0.0);
}
if (real < -20.0) {
return createComplex(-1.0, 0.0);
}
double real2 = 2.0 * real;
double imaginary2 = 2.0 * imaginary;
double d = FastMath.cosh(real2) + FastMath.cos(imaginary2);

View File

@ -996,6 +996,13 @@ public class ComplexTest {
Complex z = new Complex(3, 4);
Complex expected = new Complex(-0.000187346, 0.999356);
TestUtils.assertEquals(expected, z.tan(), 1.0e-5);
/* Check that no overflow occurs (MATH-722) */
Complex actual = new Complex(3.0, 1E10).tan();
expected = new Complex(0, 1);
TestUtils.assertEquals(expected, actual, 1.0e-5);
actual = new Complex(3.0, -1E10).tan();
expected = new Complex(0, -1);
TestUtils.assertEquals(expected, actual, 1.0e-5);
}
@Test
@ -1005,8 +1012,8 @@ public class ComplexTest {
@Test
public void testTanInf() {
TestUtils.assertSame(zeroNaN, oneInf.tan());
TestUtils.assertSame(zeroNaN, oneNegInf.tan());
TestUtils.assertSame(Complex.valueOf(0.0, 1.0), oneInf.tan());
TestUtils.assertSame(Complex.valueOf(0.0, -1.0), oneNegInf.tan());
TestUtils.assertSame(Complex.NaN, infOne.tan());
TestUtils.assertSame(Complex.NaN, negInfOne.tan());
TestUtils.assertSame(Complex.NaN, infInf.tan());
@ -1026,6 +1033,13 @@ public class ComplexTest {
Complex z = new Complex(3, 4);
Complex expected = new Complex(1.00071, 0.00490826);
TestUtils.assertEquals(expected, z.tanh(), 1.0e-5);
/* Check that no overflow occurs (MATH-722) */
Complex actual = new Complex(1E10, 3.0).tanh();
expected = new Complex(1, 0);
TestUtils.assertEquals(expected, actual, 1.0e-5);
actual = new Complex(-1E10, 3.0).tanh();
expected = new Complex(-1, 0);
TestUtils.assertEquals(expected, actual, 1.0e-5);
}
@Test
@ -1037,8 +1051,8 @@ public class ComplexTest {
public void testTanhInf() {
TestUtils.assertSame(Complex.NaN, oneInf.tanh());
TestUtils.assertSame(Complex.NaN, oneNegInf.tanh());
TestUtils.assertSame(nanZero, infOne.tanh());
TestUtils.assertSame(nanZero, negInfOne.tanh());
TestUtils.assertSame(Complex.valueOf(1.0, 0.0), infOne.tanh());
TestUtils.assertSame(Complex.valueOf(-1.0, 0.0), negInfOne.tanh());
TestUtils.assertSame(Complex.NaN, infInf.tanh());
TestUtils.assertSame(Complex.NaN, infNegInf.tanh());
TestUtils.assertSame(Complex.NaN, negInfInf.tanh());