MATH-154. Added addAndCheck, mulAndCheck, and subAndCheck MathUtils methods for long integer arguments.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@590577 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brent Worden 2007-10-31 07:23:01 +00:00
parent 828b70de30
commit 06da34fabc
3 changed files with 682 additions and 537 deletions

View File

@ -68,6 +68,66 @@ public final class MathUtils {
return (int)s;
}
/**
* Add two long integers, checking for overflow.
*
* @param a an addend
* @param b an addend
* @return the sum <code>a+b</code>
* @throws ArithmeticException if the result can not be represented as an
* long
* @since 1.2
*/
public static long addAndCheck(long a, long b) {
return addAndCheck(a, b, "overflow: add");
}
/**
* Add two long integers, checking for overflow.
*
* @param a an addend
* @param b an addend
* @param msg the message to use for any thrown exception.
* @return the sum <code>a+b</code>
* @throws ArithmeticException if the result can not be represented as an
* long
* @since 1.2
*/
private static long addAndCheck(long a, long b, String msg) {
long ret;
if (a > b) {
// use symmetry to reduce boundry cases
ret = addAndCheck(b, a, msg);
} else {
// assert a <= b
if (a < 0) {
if (b < 0) {
// check for negative overflow
if (Long.MIN_VALUE - b <= a) {
ret = a + b;
} else {
throw new ArithmeticException(msg);
}
} else {
// oppisite sign addition is always safe
ret = a + b;
}
} else {
// assert a >= 0
// assert b >= 0
// check for positive overflow
if (a <= Long.MAX_VALUE - b) {
ret = a + b;
} else {
throw new ArithmeticException(msg);
}
}
}
return ret;
}
/**
* Returns an exact representation of the <a
* href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial
@ -118,25 +178,6 @@ public final class MathUtils {
return result;
}
/**
* <p>Returns the
* <a href="http://mathworld.wolfram.com/Logarithm.html">logarithm</a>
* for base <code>b</code> of <code>x</code>.
* </p>
* <p>Returns <code>NaN<code> if either argument is negative. If
* <code>base</code> is 0 and <code>x</code> is positive, 0 is returned.
* If <code>base</code> is positive and <code>x</code> is 0,
* <code>Double.NEGATIVE_INFINITY</code> is returned. If both arguments
* are 0, the result is <code>NaN</code>.</p>
*
* @param base the base of the logarithm, must be greater than 0
* @param x argument, must be greater than 0
* @return the value of the logarithm - the number y such that base^y = x.
*/
public static double log(double base, double x) {
return Math.log(x)/Math.log(base);
}
/**
* Returns a <code>double</code> representation of the <a
* href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial
@ -475,6 +516,25 @@ public final class MathUtils {
return Math.abs(mulAndCheck(a / gcd(a, b), b));
}
/**
* <p>Returns the
* <a href="http://mathworld.wolfram.com/Logarithm.html">logarithm</a>
* for base <code>b</code> of <code>x</code>.
* </p>
* <p>Returns <code>NaN<code> if either argument is negative. If
* <code>base</code> is 0 and <code>x</code> is positive, 0 is returned.
* If <code>base</code> is positive and <code>x</code> is 0,
* <code>Double.NEGATIVE_INFINITY</code> is returned. If both arguments
* are 0, the result is <code>NaN</code>.</p>
*
* @param base the base of the logarithm, must be greater than 0
* @param x argument, must be greater than 0
* @return the value of the logarithm - the number y such that base^y = x.
*/
public static double log(double base, double x) {
return Math.log(x)/Math.log(base);
}
/**
* Multiply two integers, checking for overflow.
*
@ -493,6 +553,61 @@ public final class MathUtils {
return (int)m;
}
/**
* Multiply two long integers, checking for overflow.
*
* @param a first value
* @param b second value
* @return the product <code>a * b</code>
* @throws ArithmeticException if the result can not be represented as an
* long
* @since 1.2
*/
public static long mulAndCheck(long a, long b) {
long ret;
String msg = "overflow: multiply";
if (a > b) {
// use symmetry to reduce boundry cases
ret = mulAndCheck(b, a);
} else {
if (a < 0) {
if (b < 0) {
// check for positive overflow with negative a, negative b
if (a >= Long.MAX_VALUE / b) {
ret = a * b;
} else {
throw new ArithmeticException(msg);
}
} else if (b > 0) {
// check for negative overflow with negative a, positive b
if (Long.MIN_VALUE / b <= a) {
ret = a * b;
} else {
throw new ArithmeticException(msg);
}
} else {
// assert b == 0
ret = 0;
}
} else if (a > 0) {
// assert a > 0
// assert b > 0
// check for positive overflow with positive a, positive b
if (a <= Long.MAX_VALUE / b) {
ret = a * b;
} else {
throw new ArithmeticException(msg);
}
} else {
// assert a == 0
ret = 0;
}
}
return ret;
}
/**
* Get the next machine representable number after a number, moving
* in the direction of another number.
@ -824,4 +939,30 @@ public final class MathUtils {
}
return (int)s;
}
/**
* Subtract two long integers, checking for overflow.
*
* @param a first value
* @param b second value
* @return the difference <code>a-b</code>
* @throws ArithmeticException if the result can not be represented as an
* long
* @since 1.2
*/
public static long subAndCheck(long a, long b) {
long ret;
String msg = "overflow: subtract";
if (b == Long.MIN_VALUE) {
if (a < 0) {
ret = a - b;
} else {
throw new ArithmeticException(msg);
}
} else {
// use additive inverse
ret = addAndCheck(a, -b, msg);
}
return ret;
}
}

View File

@ -1,33 +1,30 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
* or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.apache.commons.math.util;
import java.math.BigDecimal;
import org.apache.commons.math.TestUtils;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.commons.math.TestUtils;
/**
* Test cases for the MathUtils class.
*
* @version $Revision$ $Date$
* @version $Revision$ $Date: 2007-08-16 15:36:33 -0500 (Thu, 16 Aug
* 2007) $
*/
public final class MathUtilsTest extends TestCase {
@ -41,89 +38,28 @@ public final class MathUtilsTest extends TestCase {
return suite;
}
public void testAddAndCheck() {
int big = Integer.MAX_VALUE;
int bigNeg = Integer.MIN_VALUE;
assertEquals(big, MathUtils.addAndCheck(big, 0));
try {
MathUtils.addAndCheck(big, 1);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {}
try {
MathUtils.addAndCheck(bigNeg, -1);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {}
}
public void testMulAndCheck() {
int big = Integer.MAX_VALUE;
int bigNeg = Integer.MIN_VALUE;
assertEquals(big, MathUtils.mulAndCheck(big, 1));
try {
MathUtils.mulAndCheck(big, 2);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {}
try {
MathUtils.mulAndCheck(bigNeg, 2);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {}
}
public void testSubAndCheck() {
int big = Integer.MAX_VALUE;
int bigNeg = Integer.MIN_VALUE;
assertEquals(big, MathUtils.subAndCheck(big, 0));
try {
MathUtils.subAndCheck(big, -1);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {}
try {
MathUtils.subAndCheck(bigNeg, 1);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {}
}
public void testSubAndCheckErrorMessage() {
int big = Integer.MAX_VALUE;
try {
MathUtils.subAndCheck(big, -1);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {
assertEquals("overflow: subtract", ex.getMessage());
}
}
public void testBinomialCoefficient() {
long[] bcoef5 = {1,5,10,10,5,1};
long[] bcoef6 = {1,6,15,20,15,6,1};
for (int i = 0; i < 6; i++) {
assertEquals("5 choose " + i, bcoef5[i],
MathUtils.binomialCoefficient(5,i));
}
for (int i = 0; i < 7; i++) {
assertEquals("6 choose " + i, bcoef6[i],
MathUtils.binomialCoefficient(6,i));
}
for (int n = 1; n < 10; n++) {
for (int k = 0; k <= n; k++) {
assertEquals(n + " choose " + k, binomialCoefficient(n, k),
MathUtils.binomialCoefficient(n, k));
assertEquals(n + " choose " + k,(double) binomialCoefficient(n, k),
MathUtils.binomialCoefficientDouble(n, k),Double.MIN_VALUE);
assertEquals(n + " choose " + k,
Math.log((double) binomialCoefficient(n, k)),
MathUtils.binomialCoefficientLog(n, k),10E-12);
}
}
/*
* Takes a long time for recursion to unwind, but succeeds
* and yields exact value = 2,333,606,220
assertEquals(MathUtils.binomialCoefficient(34,17),
binomialCoefficient(34,17));
/**
* Exact recursive implementation to test against
*/
private long binomialCoefficient(int n, int k) {
if ((n == k) || (k == 0)) {
return 1;
}
if ((k == 1) || (k == n - 1)) {
return n;
}
return binomialCoefficient(n - 1, k - 1) + binomialCoefficient(n - 1, k);
}
/**
* Exact direct multiplication implementation to test against
*/
private long factorial(int n) {
long result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
/** Verify that b(0,0) = 1 */
@ -133,6 +69,85 @@ public final class MathUtilsTest extends TestCase {
assertEquals(MathUtils.binomialCoefficient(0, 0), 1);
}
public void testAddAndCheck() {
int big = Integer.MAX_VALUE;
int bigNeg = Integer.MIN_VALUE;
assertEquals(big, MathUtils.addAndCheck(big, 0));
try {
MathUtils.addAndCheck(big, 1);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {
}
try {
MathUtils.addAndCheck(bigNeg, -1);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {
}
}
public void testAddAndCheckLong() {
long max = Long.MAX_VALUE;
long min = Long.MIN_VALUE;
assertEquals(max, MathUtils.addAndCheck(max, 0L));
assertEquals(min, MathUtils.addAndCheck(min, 0L));
assertEquals(max, MathUtils.addAndCheck(0L, max));
assertEquals(min, MathUtils.addAndCheck(0L, min));
assertEquals(1, MathUtils.addAndCheck(-1L, 2L));
assertEquals(1, MathUtils.addAndCheck(2L, -1L));
testAddAndCheckLongFailure(max, 1L);
testAddAndCheckLongFailure(min, -1L);
testAddAndCheckLongFailure(1L, max);
testAddAndCheckLongFailure(-1L, min);
}
private void testAddAndCheckLongFailure(long a, long b) {
try {
MathUtils.addAndCheck(a, b);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {
// success
}
}
public void testBinomialCoefficient() {
long[] bcoef5 = {
1,
5,
10,
10,
5,
1 };
long[] bcoef6 = {
1,
6,
15,
20,
15,
6,
1 };
for (int i = 0; i < 6; i++) {
assertEquals("5 choose " + i, bcoef5[i], MathUtils.binomialCoefficient(5, i));
}
for (int i = 0; i < 7; i++) {
assertEquals("6 choose " + i, bcoef6[i], MathUtils.binomialCoefficient(6, i));
}
for (int n = 1; n < 10; n++) {
for (int k = 0; k <= n; k++) {
assertEquals(n + " choose " + k, binomialCoefficient(n, k), MathUtils.binomialCoefficient(n, k));
assertEquals(n + " choose " + k, (double)binomialCoefficient(n, k), MathUtils.binomialCoefficientDouble(n, k), Double.MIN_VALUE);
assertEquals(n + " choose " + k, Math.log((double)binomialCoefficient(n, k)), MathUtils.binomialCoefficientLog(n, k), 10E-12);
}
}
/*
* Takes a long time for recursion to unwind, but succeeds and yields
* exact value = 2,333,606,220
* assertEquals(MathUtils.binomialCoefficient(34,17),
* binomialCoefficient(34,17));
*/
}
public void testBinomialCoefficientFail() {
try {
MathUtils.binomialCoefficient(4, 5);
@ -161,17 +176,44 @@ public final class MathUtilsTest extends TestCase {
;
}
double x = MathUtils.binomialCoefficientDouble(1030, 515);
assertTrue("expecting infinite binomial coefficient",
Double.isInfinite(x));
assertTrue("expecting infinite binomial coefficient", Double.isInfinite(x));
}
public void testCosh() {
double x = 3.0;
double expected = 10.06766;
assertEquals(expected, MathUtils.cosh(x), 1.0e-5);
}
public void testCoshNaN() {
assertTrue(Double.isNaN(MathUtils.cosh(Double.NaN)));
}
public void testEquals() {
double[] testArray = {
Double.NaN,
Double.POSITIVE_INFINITY,
Double.NEGATIVE_INFINITY,
1d,
0d };
for (int i = 0; i < testArray.length; i++) {
for (int j = 0; j < testArray.length; j++) {
if (i == j) {
assertTrue(MathUtils.equals(testArray[i], testArray[j]));
assertTrue(MathUtils.equals(testArray[j], testArray[i]));
} else {
assertTrue(!MathUtils.equals(testArray[i], testArray[j]));
assertTrue(!MathUtils.equals(testArray[j], testArray[i]));
}
}
}
}
public void testFactorial() {
for (int i = 1; i < 10; i++) {
assertEquals(i + "! ", factorial(i), MathUtils.factorial(i));
assertEquals(i + "! ",(double)factorial(i),
MathUtils.factorialDouble(i),Double.MIN_VALUE);
assertEquals(i + "! ",Math.log((double)factorial(i)),
MathUtils.factorialLog(i),10E-12);
assertEquals(i + "! ", (double)factorial(i), MathUtils.factorialDouble(i), Double.MIN_VALUE);
assertEquals(i + "! ", Math.log((double)factorial(i)), MathUtils.factorialLog(i), 10E-12);
}
assertEquals("0", 1, MathUtils.factorial(0));
assertEquals("0", 1.0d, MathUtils.factorialDouble(0), 1E-14);
@ -203,254 +245,7 @@ public final class MathUtilsTest extends TestCase {
} catch (ArithmeticException ex) {
;
}
assertTrue("expecting infinite factorial value",
Double.isInfinite(MathUtils.factorialDouble(171)));
}
/**
* Exact recursive implementation to test against
*/
private long binomialCoefficient(int n, int k) {
if ((n == k) || (k == 0)) {
return 1;
}
if ((k == 1) || (k == n - 1)) {
return n;
}
return binomialCoefficient(n - 1, k - 1) +
binomialCoefficient(n - 1, k);
}
/**
* Finds the largest values of n for which binomialCoefficient and
* binomialCoefficientDouble will return values that fit in a long, double,
* resp. Remove comments around test below to get this in test-report
*
public void testLimits() {
findBinomialLimits();
}
*/
private void findBinomialLimits() {
/**
* will kick out 66 as the limit for long
*/
boolean foundLimit = false;
int test = 10;
while (!foundLimit) {
try {
MathUtils.binomialCoefficient(test, test / 2);
} catch (ArithmeticException ex) {
foundLimit = true;
System.out.println
("largest n for binomialCoefficient = " + (test - 1) );
}
test++;
}
/**
* will kick out 1029 as the limit for double
*/
foundLimit = false;
test = 10;
while (!foundLimit) {
double x = MathUtils.binomialCoefficientDouble(test, test / 2);
if (Double.isInfinite(x)) {
foundLimit = true;
System.out.println
("largest n for binomialCoefficientD = " + (test - 1) );
}
test++;
}
}
/**
* Finds the largest values of n for which factiorial and
* factorialDouble will return values that fit in a long, double,
* resp. Remove comments around test below to get this in test-report
public void testFactiorialLimits() {
findFactorialLimits();
}
*/
private void findFactorialLimits() {
/**
* will kick out 20 as the limit for long
*/
boolean foundLimit = false;
int test = 10;
while (!foundLimit) {
try {
MathUtils.factorial(test);
} catch (ArithmeticException ex) {
foundLimit = true;
System.out.println
("largest n for factorial = " + (test - 1) );
}
test++;
}
/**
* will kick out 170 as the limit for double
*/
foundLimit = false;
test = 10;
while (!foundLimit) {
double x = MathUtils.factorialDouble(test);
if (Double.isInfinite(x)) {
foundLimit = true;
System.out.println
("largest n for factorialDouble = " + (test - 1) );
}
test++;
}
}
/**
* Exact direct multiplication implementation to test against
*/
private long factorial(int n) {
long result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
public void testSignDouble() {
double delta = 0.0 ;
assertEquals( 1.0, MathUtils.indicator( 2.0 ), delta ) ;
assertEquals( -1.0, MathUtils.indicator( -2.0 ), delta ) ;
}
public void testSignFloat() {
float delta = 0.0F ;
assertEquals( 1.0F, MathUtils.indicator( 2.0F ), delta ) ;
assertEquals( -1.0F, MathUtils.indicator( -2.0F ), delta ) ;
}
public void testSignByte() {
assertEquals( (byte)1, MathUtils.indicator( (byte)2 ) ) ;
assertEquals( (byte)(-1), MathUtils.indicator( (byte)(-2) ) ) ;
}
public void testSignShort() {
assertEquals( (short)1, MathUtils.indicator( (short)2 ) ) ;
assertEquals( (short)(-1), MathUtils.indicator( (short)(-2) ) ) ;
}
public void testSignInt() {
assertEquals( (int)1, MathUtils.indicator( (int)(2) ) ) ;
assertEquals( (int)(-1), MathUtils.indicator( (int)(-2) ) ) ;
}
public void testSignLong() {
assertEquals( 1L, MathUtils.indicator( 2L ) ) ;
assertEquals( -1L, MathUtils.indicator( -2L ) ) ;
}
public void testIndicatorDouble() {
double delta = 0.0 ;
assertEquals( 1.0, MathUtils.indicator( 2.0 ), delta ) ;
assertEquals( 1.0, MathUtils.indicator( 0.0 ), delta ) ;
assertEquals( -1.0, MathUtils.indicator( -2.0 ), delta ) ;
}
public void testIndicatorFloat() {
float delta = 0.0F ;
assertEquals( 1.0F, MathUtils.indicator( 2.0F ), delta ) ;
assertEquals( 1.0F, MathUtils.indicator( 0.0F ), delta ) ;
assertEquals( -1.0F, MathUtils.indicator( -2.0F ), delta ) ;
}
public void testIndicatorByte() {
assertEquals( (byte)1, MathUtils.indicator( (byte)2 ) ) ;
assertEquals( (byte)1, MathUtils.indicator( (byte)0 ) ) ;
assertEquals( (byte)(-1), MathUtils.indicator( (byte)(-2) ) ) ;
}
public void testIndicatorShort() {
assertEquals( (short)1, MathUtils.indicator( (short)2 ) ) ;
assertEquals( (short)1, MathUtils.indicator( (short)0 ) ) ;
assertEquals( (short)(-1), MathUtils.indicator( (short)(-2) ) ) ;
}
public void testIndicatorInt() {
assertEquals( (int)1, MathUtils.indicator( (int)(2) ) ) ;
assertEquals( (int)1, MathUtils.indicator( (int)(0) ) ) ;
assertEquals( (int)(-1), MathUtils.indicator( (int)(-2) ) ) ;
}
public void testIndicatorLong() {
assertEquals( 1L, MathUtils.indicator( 2L ) ) ;
assertEquals( 1L, MathUtils.indicator( 0L ) ) ;
assertEquals( -1L, MathUtils.indicator( -2L ) ) ;
}
public void testCosh() {
double x = 3.0;
double expected = 10.06766;
assertEquals(expected, MathUtils.cosh(x), 1.0e-5);
}
public void testSinh() {
double x = 3.0;
double expected = 10.01787;
assertEquals(expected, MathUtils.sinh(x), 1.0e-5);
}
public void testCoshNaN() {
assertTrue(Double.isNaN(MathUtils.cosh(Double.NaN)));
}
public void testSinhNaN() {
assertTrue(Double.isNaN(MathUtils.sinh(Double.NaN)));
}
public void testEquals() {
double[] testArray = {Double.NaN, Double.POSITIVE_INFINITY,
Double.NEGATIVE_INFINITY, 1d, 0d};
for (int i = 0; i < testArray.length; i++) {
for (int j = 0; j < testArray.length; j ++) {
if (i == j) {
assertTrue(MathUtils.equals(testArray[i], testArray[j]));
assertTrue(MathUtils.equals(testArray[j], testArray[i]));
} else {
assertTrue(!MathUtils.equals(testArray[i], testArray[j]));
assertTrue(!MathUtils.equals(testArray[j], testArray[i]));
}
}
}
}
public void testHash() {
double[] testArray = {Double.NaN, Double.POSITIVE_INFINITY,
Double.NEGATIVE_INFINITY, 1d, 0d, 1E-14, (1 + 1E-14),
Double.MIN_VALUE, Double.MAX_VALUE};
for (int i = 0; i < testArray.length; i++) {
for (int j = 0; j < testArray.length; j ++) {
if (i == j) {
assertEquals(MathUtils.hash(testArray[i]), MathUtils.hash(testArray[j]));
assertEquals(MathUtils.hash(testArray[j]), MathUtils.hash(testArray[i]));
} else {
assertTrue(MathUtils.hash(testArray[i]) != MathUtils.hash(testArray[j]));
assertTrue(MathUtils.hash(testArray[j]) != MathUtils.hash(testArray[i]));
}
}
}
}
public void testLog() {
assertEquals(2.0, MathUtils.log(2,4), 0);
assertEquals(3.0, MathUtils.log(2,8), 0);
assertTrue(Double.isNaN(MathUtils.log(-1, 1)));
assertTrue(Double.isNaN(MathUtils.log(1, -1)));
assertTrue(Double.isNaN(MathUtils.log(0, 0)));
assertEquals(0, MathUtils.log(0, 10), 0);
assertEquals(Double.NEGATIVE_INFINITY, MathUtils.log(10, 0), 0);
assertTrue("expecting infinite factorial value", Double.isInfinite(MathUtils.factorialDouble(171)));
}
public void testGcd() {
@ -476,6 +271,68 @@ public final class MathUtilsTest extends TestCase {
assertEquals(1, MathUtils.gcd(-a, -c));
}
public void testHash() {
double[] testArray = {
Double.NaN,
Double.POSITIVE_INFINITY,
Double.NEGATIVE_INFINITY,
1d,
0d,
1E-14,
(1 + 1E-14),
Double.MIN_VALUE,
Double.MAX_VALUE };
for (int i = 0; i < testArray.length; i++) {
for (int j = 0; j < testArray.length; j++) {
if (i == j) {
assertEquals(MathUtils.hash(testArray[i]), MathUtils.hash(testArray[j]));
assertEquals(MathUtils.hash(testArray[j]), MathUtils.hash(testArray[i]));
} else {
assertTrue(MathUtils.hash(testArray[i]) != MathUtils.hash(testArray[j]));
assertTrue(MathUtils.hash(testArray[j]) != MathUtils.hash(testArray[i]));
}
}
}
}
public void testIndicatorByte() {
assertEquals((byte)1, MathUtils.indicator((byte)2));
assertEquals((byte)1, MathUtils.indicator((byte)0));
assertEquals((byte)(-1), MathUtils.indicator((byte)(-2)));
}
public void testIndicatorDouble() {
double delta = 0.0;
assertEquals(1.0, MathUtils.indicator(2.0), delta);
assertEquals(1.0, MathUtils.indicator(0.0), delta);
assertEquals(-1.0, MathUtils.indicator(-2.0), delta);
}
public void testIndicatorFloat() {
float delta = 0.0F;
assertEquals(1.0F, MathUtils.indicator(2.0F), delta);
assertEquals(1.0F, MathUtils.indicator(0.0F), delta);
assertEquals(-1.0F, MathUtils.indicator(-2.0F), delta);
}
public void testIndicatorInt() {
assertEquals((int)1, MathUtils.indicator((int)(2)));
assertEquals((int)1, MathUtils.indicator((int)(0)));
assertEquals((int)(-1), MathUtils.indicator((int)(-2)));
}
public void testIndicatorLong() {
assertEquals(1L, MathUtils.indicator(2L));
assertEquals(1L, MathUtils.indicator(0L));
assertEquals(-1L, MathUtils.indicator(-2L));
}
public void testIndicatorShort() {
assertEquals((short)1, MathUtils.indicator((short)2));
assertEquals((short)1, MathUtils.indicator((short)0));
assertEquals((short)(-1), MathUtils.indicator((short)(-2)));
}
public void testLcm() {
int a = 30;
int b = 50;
@ -497,112 +354,59 @@ public final class MathUtilsTest extends TestCase {
// expected
}
}
public void testRoundFloat() {
float x = 1.234567890f;
assertEquals(1.23f, MathUtils.round(x, 2), 0.0);
assertEquals(1.235f, MathUtils.round(x, 3), 0.0);
assertEquals(1.2346f, MathUtils.round(x, 4), 0.0);
// BZ 35904
assertEquals(30.1f, MathUtils.round(30.095f, 2), 0.0f);
assertEquals(30.1f, MathUtils.round(30.095f, 1), 0.0f);
assertEquals(50.09f, MathUtils.round(50.085f, 2), 0.0f);
assertEquals(50.19f, MathUtils.round(50.185f, 2), 0.0f);
assertEquals(50.01f, MathUtils.round(50.005f, 2), 0.0f);
assertEquals(30.01f, MathUtils.round(30.005f, 2), 0.0f);
assertEquals(30.65f, MathUtils.round(30.645f, 2), 0.0f);
assertEquals(1.24f, MathUtils.round(x, 2, BigDecimal.ROUND_CEILING), 0.0);
assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_CEILING), 0.0);
assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_CEILING), 0.0);
assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_CEILING), 0.0);
assertEquals(-1.234f, MathUtils.round(-x, 3, BigDecimal.ROUND_CEILING), 0.0);
assertEquals(-1.2345f, MathUtils.round(-x, 4, BigDecimal.ROUND_CEILING), 0.0);
assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_DOWN), 0.0);
assertEquals(1.234f, MathUtils.round(x, 3, BigDecimal.ROUND_DOWN), 0.0);
assertEquals(1.2345f, MathUtils.round(x, 4, BigDecimal.ROUND_DOWN), 0.0);
assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_DOWN), 0.0);
assertEquals(-1.234f, MathUtils.round(-x, 3, BigDecimal.ROUND_DOWN), 0.0);
assertEquals(-1.2345f, MathUtils.round(-x, 4, BigDecimal.ROUND_DOWN), 0.0);
assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_FLOOR), 0.0);
assertEquals(1.234f, MathUtils.round(x, 3, BigDecimal.ROUND_FLOOR), 0.0);
assertEquals(1.2345f, MathUtils.round(x, 4, BigDecimal.ROUND_FLOOR), 0.0);
assertEquals(-1.24f, MathUtils.round(-x, 2, BigDecimal.ROUND_FLOOR), 0.0);
assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_FLOOR), 0.0);
assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_FLOOR), 0.0);
assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(1.234f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(-1.234f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(1.234f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(-1.234f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(1.236f, MathUtils.round(1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(-1.236f, MathUtils.round(-1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(1.235f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(-1.235f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(-1.23f, MathUtils.round(-1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
assertEquals(1.23f, MathUtils.round(1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
public void testLog() {
assertEquals(2.0, MathUtils.log(2, 4), 0);
assertEquals(3.0, MathUtils.log(2, 8), 0);
assertTrue(Double.isNaN(MathUtils.log(-1, 1)));
assertTrue(Double.isNaN(MathUtils.log(1, -1)));
assertTrue(Double.isNaN(MathUtils.log(0, 0)));
assertEquals(0, MathUtils.log(0, 10), 0);
assertEquals(Double.NEGATIVE_INFINITY, MathUtils.log(10, 0), 0);
}
public void testMulAndCheck() {
int big = Integer.MAX_VALUE;
int bigNeg = Integer.MIN_VALUE;
assertEquals(big, MathUtils.mulAndCheck(big, 1));
try {
MathUtils.round(1.234f, 2, BigDecimal.ROUND_UNNECESSARY);
fail();
MathUtils.mulAndCheck(big, 2);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {
}
try {
MathUtils.mulAndCheck(bigNeg, 2);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {
}
}
public void testMulAndCheckLong() {
long max = Long.MAX_VALUE;
long min = Long.MIN_VALUE;
assertEquals(max, MathUtils.mulAndCheck(max, 1L));
assertEquals(min, MathUtils.mulAndCheck(min, 1L));
assertEquals(0L, MathUtils.mulAndCheck(max, 0L));
assertEquals(0L, MathUtils.mulAndCheck(min, 0L));
assertEquals(max, MathUtils.mulAndCheck(1L, max));
assertEquals(min, MathUtils.mulAndCheck(1L, min));
assertEquals(0L, MathUtils.mulAndCheck(0L, max));
assertEquals(0L, MathUtils.mulAndCheck(0L, min));
testMulAndCheckLongFailure(max, 2L);
testMulAndCheckLongFailure(2L, max);
testMulAndCheckLongFailure(min, 2L);
testMulAndCheckLongFailure(2L, min);
testMulAndCheckLongFailure(min, -1L);
testMulAndCheckLongFailure(-1L, min);
}
private void testMulAndCheckLongFailure(long a, long b) {
try {
MathUtils.mulAndCheck(a, b);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {
// success
}
assertEquals(1.24f, MathUtils.round(x, 2, BigDecimal.ROUND_UP), 0.0);
assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_UP), 0.0);
assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_UP), 0.0);
assertEquals(-1.24f, MathUtils.round(-x, 2, BigDecimal.ROUND_UP), 0.0);
assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_UP), 0.0);
assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_UP), 0.0);
try {
MathUtils.round(1.234f, 2, 1923);
fail();
} catch (IllegalArgumentException ex) {
// success
}
// special values
TestUtils.assertEquals(Float.NaN, MathUtils.round(Float.NaN, 2), 0.0f);
assertEquals(0.0f, MathUtils.round(0.0f, 2), 0.0f);
assertEquals(Float.POSITIVE_INFINITY, MathUtils.round(Float.POSITIVE_INFINITY, 2), 0.0f);
assertEquals(Float.NEGATIVE_INFINITY, MathUtils.round(Float.NEGATIVE_INFINITY, 2), 0.0f);
}
public void testNextAfterSpecialCases() {
assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.NEGATIVE_INFINITY, 0)));
assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.POSITIVE_INFINITY, 0)));
assertTrue(Double.isNaN(MathUtils.nextAfter(Double.NaN, 0)));
assertTrue(Double.isInfinite(MathUtils.nextAfter( Double.MAX_VALUE, Double.POSITIVE_INFINITY)));
assertTrue(Double.isInfinite(MathUtils.nextAfter(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY)));
assertEquals( Double.MIN_VALUE, MathUtils.nextAfter(0, 1), 0);
assertEquals(-Double.MIN_VALUE, MathUtils.nextAfter(0, -1), 0);
assertEquals(0, MathUtils.nextAfter( Double.MIN_VALUE, -1), 0);
assertEquals(0, MathUtils.nextAfter(-Double.MIN_VALUE, 1), 0);
}
public void testNextAfter() {
@ -668,6 +472,18 @@ public final class MathUtilsTest extends TestCase {
}
public void testNextAfterSpecialCases() {
assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.NEGATIVE_INFINITY, 0)));
assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.POSITIVE_INFINITY, 0)));
assertTrue(Double.isNaN(MathUtils.nextAfter(Double.NaN, 0)));
assertTrue(Double.isInfinite(MathUtils.nextAfter(Double.MAX_VALUE, Double.POSITIVE_INFINITY)));
assertTrue(Double.isInfinite(MathUtils.nextAfter(-Double.MAX_VALUE, Double.NEGATIVE_INFINITY)));
assertEquals(Double.MIN_VALUE, MathUtils.nextAfter(0, 1), 0);
assertEquals(-Double.MIN_VALUE, MathUtils.nextAfter(0, -1), 0);
assertEquals(0, MathUtils.nextAfter(Double.MIN_VALUE, -1), 0);
assertEquals(0, MathUtils.nextAfter(-Double.MIN_VALUE, 1), 0);
}
public void testRoundDouble() {
double x = 1.234567890;
assertEquals(1.23, MathUtils.round(x, 2), 0.0);
@ -676,8 +492,7 @@ public final class MathUtilsTest extends TestCase {
// JIRA MATH-151
assertEquals(39.25, MathUtils.round(39.245, 2), 0.0);
assertEquals(39.24,MathUtils.round(39.245, 2,
BigDecimal.ROUND_DOWN), 0.0);
assertEquals(39.24, MathUtils.round(39.245, 2, BigDecimal.ROUND_DOWN), 0.0);
double xx = 39.0;
xx = xx + 245d / 1000d;
assertEquals(39.25, MathUtils.round(xx, 2), 0.0);
@ -776,4 +591,189 @@ public final class MathUtilsTest extends TestCase {
assertEquals(Double.POSITIVE_INFINITY, MathUtils.round(Double.POSITIVE_INFINITY, 2), 0.0);
assertEquals(Double.NEGATIVE_INFINITY, MathUtils.round(Double.NEGATIVE_INFINITY, 2), 0.0);
}
public void testRoundFloat() {
float x = 1.234567890f;
assertEquals(1.23f, MathUtils.round(x, 2), 0.0);
assertEquals(1.235f, MathUtils.round(x, 3), 0.0);
assertEquals(1.2346f, MathUtils.round(x, 4), 0.0);
// BZ 35904
assertEquals(30.1f, MathUtils.round(30.095f, 2), 0.0f);
assertEquals(30.1f, MathUtils.round(30.095f, 1), 0.0f);
assertEquals(50.09f, MathUtils.round(50.085f, 2), 0.0f);
assertEquals(50.19f, MathUtils.round(50.185f, 2), 0.0f);
assertEquals(50.01f, MathUtils.round(50.005f, 2), 0.0f);
assertEquals(30.01f, MathUtils.round(30.005f, 2), 0.0f);
assertEquals(30.65f, MathUtils.round(30.645f, 2), 0.0f);
assertEquals(1.24f, MathUtils.round(x, 2, BigDecimal.ROUND_CEILING), 0.0);
assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_CEILING), 0.0);
assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_CEILING), 0.0);
assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_CEILING), 0.0);
assertEquals(-1.234f, MathUtils.round(-x, 3, BigDecimal.ROUND_CEILING), 0.0);
assertEquals(-1.2345f, MathUtils.round(-x, 4, BigDecimal.ROUND_CEILING), 0.0);
assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_DOWN), 0.0);
assertEquals(1.234f, MathUtils.round(x, 3, BigDecimal.ROUND_DOWN), 0.0);
assertEquals(1.2345f, MathUtils.round(x, 4, BigDecimal.ROUND_DOWN), 0.0);
assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_DOWN), 0.0);
assertEquals(-1.234f, MathUtils.round(-x, 3, BigDecimal.ROUND_DOWN), 0.0);
assertEquals(-1.2345f, MathUtils.round(-x, 4, BigDecimal.ROUND_DOWN), 0.0);
assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_FLOOR), 0.0);
assertEquals(1.234f, MathUtils.round(x, 3, BigDecimal.ROUND_FLOOR), 0.0);
assertEquals(1.2345f, MathUtils.round(x, 4, BigDecimal.ROUND_FLOOR), 0.0);
assertEquals(-1.24f, MathUtils.round(-x, 2, BigDecimal.ROUND_FLOOR), 0.0);
assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_FLOOR), 0.0);
assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_FLOOR), 0.0);
assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(1.234f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(-1.234f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_DOWN), 0.0);
assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(1.234f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(-1.234f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(1.236f, MathUtils.round(1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(-1.236f, MathUtils.round(-1.2355f, 3, BigDecimal.ROUND_HALF_EVEN), 0.0);
assertEquals(1.23f, MathUtils.round(x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(-1.23f, MathUtils.round(-x, 2, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(1.235f, MathUtils.round(1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(-1.235f, MathUtils.round(-1.2345f, 3, BigDecimal.ROUND_HALF_UP), 0.0);
assertEquals(-1.23f, MathUtils.round(-1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
assertEquals(1.23f, MathUtils.round(1.23f, 2, BigDecimal.ROUND_UNNECESSARY), 0.0);
try {
MathUtils.round(1.234f, 2, BigDecimal.ROUND_UNNECESSARY);
fail();
} catch (ArithmeticException ex) {
// success
}
assertEquals(1.24f, MathUtils.round(x, 2, BigDecimal.ROUND_UP), 0.0);
assertEquals(1.235f, MathUtils.round(x, 3, BigDecimal.ROUND_UP), 0.0);
assertEquals(1.2346f, MathUtils.round(x, 4, BigDecimal.ROUND_UP), 0.0);
assertEquals(-1.24f, MathUtils.round(-x, 2, BigDecimal.ROUND_UP), 0.0);
assertEquals(-1.235f, MathUtils.round(-x, 3, BigDecimal.ROUND_UP), 0.0);
assertEquals(-1.2346f, MathUtils.round(-x, 4, BigDecimal.ROUND_UP), 0.0);
try {
MathUtils.round(1.234f, 2, 1923);
fail();
} catch (IllegalArgumentException ex) {
// success
}
// special values
TestUtils.assertEquals(Float.NaN, MathUtils.round(Float.NaN, 2), 0.0f);
assertEquals(0.0f, MathUtils.round(0.0f, 2), 0.0f);
assertEquals(Float.POSITIVE_INFINITY, MathUtils.round(Float.POSITIVE_INFINITY, 2), 0.0f);
assertEquals(Float.NEGATIVE_INFINITY, MathUtils.round(Float.NEGATIVE_INFINITY, 2), 0.0f);
}
public void testSignByte() {
assertEquals((byte)1, MathUtils.indicator((byte)2));
assertEquals((byte)(-1), MathUtils.indicator((byte)(-2)));
}
public void testSignDouble() {
double delta = 0.0;
assertEquals(1.0, MathUtils.indicator(2.0), delta);
assertEquals(-1.0, MathUtils.indicator(-2.0), delta);
}
public void testSignFloat() {
float delta = 0.0F;
assertEquals(1.0F, MathUtils.indicator(2.0F), delta);
assertEquals(-1.0F, MathUtils.indicator(-2.0F), delta);
}
public void testSignInt() {
assertEquals((int)1, MathUtils.indicator((int)(2)));
assertEquals((int)(-1), MathUtils.indicator((int)(-2)));
}
public void testSignLong() {
assertEquals(1L, MathUtils.indicator(2L));
assertEquals(-1L, MathUtils.indicator(-2L));
}
public void testSignShort() {
assertEquals((short)1, MathUtils.indicator((short)2));
assertEquals((short)(-1), MathUtils.indicator((short)(-2)));
}
public void testSinh() {
double x = 3.0;
double expected = 10.01787;
assertEquals(expected, MathUtils.sinh(x), 1.0e-5);
}
public void testSinhNaN() {
assertTrue(Double.isNaN(MathUtils.sinh(Double.NaN)));
}
public void testSubAndCheck() {
int big = Integer.MAX_VALUE;
int bigNeg = Integer.MIN_VALUE;
assertEquals(big, MathUtils.subAndCheck(big, 0));
try {
MathUtils.subAndCheck(big, -1);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {
}
try {
MathUtils.subAndCheck(bigNeg, 1);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {
}
}
public void testSubAndCheckErrorMessage() {
int big = Integer.MAX_VALUE;
try {
MathUtils.subAndCheck(big, -1);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {
assertEquals("overflow: subtract", ex.getMessage());
}
}
public void testSubAndCheckLong() {
long max = Long.MAX_VALUE;
long min = Long.MIN_VALUE;
assertEquals(max, MathUtils.subAndCheck(max, 0));
assertEquals(min, MathUtils.subAndCheck(min, 0));
assertEquals(-max, MathUtils.subAndCheck(0, max));
testSubAndCheckLongFailure(0L, min);
testSubAndCheckLongFailure(max, -1L);
testSubAndCheckLongFailure(min, 1L);
}
private void testSubAndCheckLongFailure(long a, long b) {
try {
MathUtils.subAndCheck(a, b);
fail("Expecting ArithmeticException");
} catch (ArithmeticException ex) {
// success
}
}
}

View File

@ -98,6 +98,10 @@ Commons Math Release Notes</title>
<action dev="brentworden" type="update" issue="MATH-170" due-to="David J. M. Karlsen">
Added SynchronizedDescriptiveStatistics class.
</action>
<action dev="brentworden" type="update" issue="MATH-154" due-to="Remi Arntzen">
Added addAndCheck, mulAndCheck, and subAndCheck MathUtils methods for
long integer arguments.
</action>
</release>
<release version="1.1" date="2005-12-17"
description="This is a maintenance release containing bug fixes and enhancements.