Renamed ArithmeticsUtils to ArithmeticUtils (MATH-689)

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1182787 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sebastien Brisard 2011-10-13 11:20:48 +00:00
parent 6a5fe463ea
commit 0b3440441b
9 changed files with 201 additions and 201 deletions

View File

@ -22,7 +22,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.math.fraction.BigFraction; import org.apache.commons.math.fraction.BigFraction;
import org.apache.commons.math.util.ArithmeticsUtils; import org.apache.commons.math.util.ArithmeticUtils;
import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.FastMath;
/** /**
@ -326,7 +326,7 @@ public class PolynomialsUtils {
final int[][] coeff = new int[dp1][dp1]; final int[][] coeff = new int[dp1][dp1];
for (int i = 0; i < dp1; i++){ for (int i = 0; i < dp1; i++){
for(int j = 0; j <= i; j++){ for(int j = 0; j <= i; j++){
coeff[i][j] = (int) ArithmeticsUtils.binomialCoefficient(i, j); coeff[i][j] = (int) ArithmeticUtils.binomialCoefficient(i, j);
} }
} }

View File

@ -23,7 +23,7 @@ import org.apache.commons.math.exception.NotPositiveException;
import org.apache.commons.math.exception.NotStrictlyPositiveException; import org.apache.commons.math.exception.NotStrictlyPositiveException;
import org.apache.commons.math.exception.NumberIsTooLargeException; import org.apache.commons.math.exception.NumberIsTooLargeException;
import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.util.ArithmeticsUtils; import org.apache.commons.math.util.ArithmeticUtils;
import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.FastMath;
/** /**
@ -231,9 +231,9 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
* @return PMF for the distribution. * @return PMF for the distribution.
*/ */
private double probability(int n, int m, int k, int x) { private double probability(int n, int m, int k, int x) {
return FastMath.exp(ArithmeticsUtils.binomialCoefficientLog(m, x) + return FastMath.exp(ArithmeticUtils.binomialCoefficientLog(m, x) +
ArithmeticsUtils.binomialCoefficientLog(n - m, k - x) - ArithmeticUtils.binomialCoefficientLog(n - m, k - x) -
ArithmeticsUtils.binomialCoefficientLog(n, k)); ArithmeticUtils.binomialCoefficientLog(n, k));
} }
/** /**

View File

@ -22,7 +22,7 @@ import org.apache.commons.math.exception.OutOfRangeException;
import org.apache.commons.math.exception.NotPositiveException; import org.apache.commons.math.exception.NotPositiveException;
import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.special.Beta; import org.apache.commons.math.special.Beta;
import org.apache.commons.math.util.ArithmeticsUtils; import org.apache.commons.math.util.ArithmeticUtils;
import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.FastMath;
/** /**
@ -128,7 +128,7 @@ public class PascalDistributionImpl extends AbstractIntegerDistribution
if (x < 0) { if (x < 0) {
ret = 0.0; ret = 0.0;
} else { } else {
ret = ArithmeticsUtils.binomialCoefficientDouble(x + ret = ArithmeticUtils.binomialCoefficientDouble(x +
numberOfSuccesses - 1, numberOfSuccesses - 1) * numberOfSuccesses - 1, numberOfSuccesses - 1) *
FastMath.pow(probabilityOfSuccess, numberOfSuccesses) * FastMath.pow(probabilityOfSuccess, numberOfSuccesses) *
FastMath.pow(1.0 - probabilityOfSuccess, x); FastMath.pow(1.0 - probabilityOfSuccess, x);

View File

@ -23,7 +23,7 @@ import org.apache.commons.math.FieldElement;
import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.exception.MathArithmeticException; import org.apache.commons.math.exception.MathArithmeticException;
import org.apache.commons.math.exception.NullArgumentException; import org.apache.commons.math.exception.NullArgumentException;
import org.apache.commons.math.util.ArithmeticsUtils; import org.apache.commons.math.util.ArithmeticUtils;
import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.FastMath;
/** /**
@ -268,7 +268,7 @@ public class Fraction
den = -den; den = -den;
} }
// reduce numerator and denominator by greatest common denominator. // reduce numerator and denominator by greatest common denominator.
final int d = ArithmeticsUtils.gcd(num, den); final int d = ArithmeticUtils.gcd(num, den);
if (d > 1) { if (d > 1) {
num /= d; num /= d;
den /= d; den /= d;
@ -486,15 +486,15 @@ public class Fraction
} }
// if denominators are randomly distributed, d1 will be 1 about 61% // if denominators are randomly distributed, d1 will be 1 about 61%
// of the time. // of the time.
int d1 = ArithmeticsUtils.gcd(denominator, fraction.denominator); int d1 = ArithmeticUtils.gcd(denominator, fraction.denominator);
if (d1==1) { if (d1==1) {
// result is ( (u*v' +/- u'v) / u'v') // result is ( (u*v' +/- u'v) / u'v')
int uvp = ArithmeticsUtils.mulAndCheck(numerator, fraction.denominator); int uvp = ArithmeticUtils.mulAndCheck(numerator, fraction.denominator);
int upv = ArithmeticsUtils.mulAndCheck(fraction.numerator, denominator); int upv = ArithmeticUtils.mulAndCheck(fraction.numerator, denominator);
return new Fraction return new Fraction
(isAdd ? ArithmeticsUtils.addAndCheck(uvp, upv) : (isAdd ? ArithmeticUtils.addAndCheck(uvp, upv) :
ArithmeticsUtils.subAndCheck(uvp, upv), ArithmeticUtils.subAndCheck(uvp, upv),
ArithmeticsUtils.mulAndCheck(denominator, fraction.denominator)); ArithmeticUtils.mulAndCheck(denominator, fraction.denominator));
} }
// the quantity 't' requires 65 bits of precision; see knuth 4.5.1 // the quantity 't' requires 65 bits of precision; see knuth 4.5.1
// exercise 7. we're going to use a BigInteger. // exercise 7. we're going to use a BigInteger.
@ -507,7 +507,7 @@ public class Fraction
// but d2 doesn't need extra precision because // but d2 doesn't need extra precision because
// d2 = gcd(t,d1) = gcd(t mod d1, d1) // d2 = gcd(t,d1) = gcd(t mod d1, d1)
int tmodd1 = t.mod(BigInteger.valueOf(d1)).intValue(); int tmodd1 = t.mod(BigInteger.valueOf(d1)).intValue();
int d2 = (tmodd1==0)?d1:ArithmeticsUtils.gcd(tmodd1, d1); int d2 = (tmodd1==0)?d1:ArithmeticUtils.gcd(tmodd1, d1);
// result is (t/d2) / (u'/d1)(v'/d2) // result is (t/d2) / (u'/d1)(v'/d2)
BigInteger w = t.divide(BigInteger.valueOf(d2)); BigInteger w = t.divide(BigInteger.valueOf(d2));
@ -516,7 +516,7 @@ public class Fraction
w); w);
} }
return new Fraction (w.intValue(), return new Fraction (w.intValue(),
ArithmeticsUtils.mulAndCheck(denominator/d1, ArithmeticUtils.mulAndCheck(denominator/d1,
fraction.denominator/d2)); fraction.denominator/d2));
} }
@ -539,11 +539,11 @@ public class Fraction
} }
// knuth 4.5.1 // knuth 4.5.1
// make sure we don't overflow unless the result *must* overflow. // make sure we don't overflow unless the result *must* overflow.
int d1 = ArithmeticsUtils.gcd(numerator, fraction.denominator); int d1 = ArithmeticUtils.gcd(numerator, fraction.denominator);
int d2 = ArithmeticsUtils.gcd(fraction.numerator, denominator); int d2 = ArithmeticUtils.gcd(fraction.numerator, denominator);
return getReducedFraction return getReducedFraction
(ArithmeticsUtils.mulAndCheck(numerator/d1, fraction.numerator/d2), (ArithmeticUtils.mulAndCheck(numerator/d1, fraction.numerator/d2),
ArithmeticsUtils.mulAndCheck(denominator/d2, fraction.denominator/d1)); ArithmeticUtils.mulAndCheck(denominator/d2, fraction.denominator/d1));
} }
/** /**
@ -618,7 +618,7 @@ public class Fraction
denominator = -denominator; denominator = -denominator;
} }
// simplify fraction. // simplify fraction.
int gcd = ArithmeticsUtils.gcd(numerator, denominator); int gcd = ArithmeticUtils.gcd(numerator, denominator);
numerator /= gcd; numerator /= gcd;
denominator /= gcd; denominator /= gcd;
return new Fraction(numerator, denominator); return new Fraction(numerator, denominator);

View File

@ -40,7 +40,7 @@ import org.apache.commons.math.exception.MathInternalError;
import org.apache.commons.math.exception.NotStrictlyPositiveException; import org.apache.commons.math.exception.NotStrictlyPositiveException;
import org.apache.commons.math.exception.NumberIsTooLargeException; import org.apache.commons.math.exception.NumberIsTooLargeException;
import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.util.ArithmeticsUtils; import org.apache.commons.math.util.ArithmeticUtils;
import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.FastMath;
import org.apache.commons.math.util.ResizableDoubleArray; import org.apache.commons.math.util.ResizableDoubleArray;
@ -148,7 +148,7 @@ public class RandomDataImpl implements RandomData, Serializable {
final ResizableDoubleArray ra = new ResizableDoubleArray(20); final ResizableDoubleArray ra = new ResizableDoubleArray(20);
while (qi < 1) { while (qi < 1) {
qi += FastMath.pow(LN2, i) / ArithmeticsUtils.factorial(i); qi += FastMath.pow(LN2, i) / ArithmeticUtils.factorial(i);
ra.addElement(qi); ra.addElement(qi);
++i; ++i;
} }
@ -424,7 +424,7 @@ public class RandomDataImpl implements RandomData, Serializable {
final double lambda = FastMath.floor(mean); final double lambda = FastMath.floor(mean);
final double lambdaFractional = mean - lambda; final double lambdaFractional = mean - lambda;
final double logLambda = FastMath.log(lambda); final double logLambda = FastMath.log(lambda);
final double logLambdaFactorial = ArithmeticsUtils.factorialLog((int) lambda); final double logLambdaFactorial = ArithmeticUtils.factorialLog((int) lambda);
final long y2 = lambdaFractional < Double.MIN_VALUE ? 0 : nextPoisson(lambdaFractional); final long y2 = lambdaFractional < Double.MIN_VALUE ? 0 : nextPoisson(lambdaFractional);
final double delta = FastMath.sqrt(lambda * FastMath.log(32 * lambda / FastMath.PI + 1)); final double delta = FastMath.sqrt(lambda * FastMath.log(32 * lambda / FastMath.PI + 1));
final double halfDelta = delta / 2; final double halfDelta = delta / 2;
@ -479,7 +479,7 @@ public class RandomDataImpl implements RandomData, Serializable {
if (v > qr) { if (v > qr) {
continue; continue;
} }
if (v < y * logLambda - ArithmeticsUtils.factorialLog((int) (y + lambda)) + logLambdaFactorial) { if (v < y * logLambda - ArithmeticUtils.factorialLog((int) (y + lambda)) + logLambdaFactorial) {
y = lambda + y; y = lambda + y;
break; break;
} }

View File

@ -28,7 +28,7 @@ import org.apache.commons.math.exception.util.LocalizedFormats;
* *
* @version $Id$ * @version $Id$
*/ */
public final class ArithmeticsUtils { public final class ArithmeticUtils {
/** All long-representable factorials */ /** All long-representable factorials */
static final long[] FACTORIALS = new long[] { static final long[] FACTORIALS = new long[] {
@ -41,7 +41,7 @@ public final class ArithmeticsUtils {
6402373705728000l, 121645100408832000l, 2432902008176640000l }; 6402373705728000l, 121645100408832000l, 2432902008176640000l };
/** Private constructor. */ /** Private constructor. */
private ArithmeticsUtils() { private ArithmeticUtils() {
super(); super();
} }
@ -74,7 +74,7 @@ public final class ArithmeticsUtils {
* @since 1.2 * @since 1.2
*/ */
public static long addAndCheck(long a, long b) { public static long addAndCheck(long a, long b) {
return ArithmeticsUtils.addAndCheck(a, b, LocalizedFormats.OVERFLOW_IN_ADDITION); return ArithmeticUtils.addAndCheck(a, b, LocalizedFormats.OVERFLOW_IN_ADDITION);
} }
/** /**
@ -103,7 +103,7 @@ public final class ArithmeticsUtils {
* represented by a long integer. * represented by a long integer.
*/ */
public static long binomialCoefficient(final int n, final int k) { public static long binomialCoefficient(final int n, final int k) {
ArithmeticsUtils.checkBinomial(n, k); ArithmeticUtils.checkBinomial(n, k);
if ((n == k) || (k == 0)) { if ((n == k) || (k == 0)) {
return 1; return 1;
} }
@ -180,7 +180,7 @@ public final class ArithmeticsUtils {
* @throws IllegalArgumentException if preconditions are not met. * @throws IllegalArgumentException if preconditions are not met.
*/ */
public static double binomialCoefficientDouble(final int n, final int k) { public static double binomialCoefficientDouble(final int n, final int k) {
ArithmeticsUtils.checkBinomial(n, k); ArithmeticUtils.checkBinomial(n, k);
if ((n == k) || (k == 0)) { if ((n == k) || (k == 0)) {
return 1d; return 1d;
} }
@ -221,7 +221,7 @@ public final class ArithmeticsUtils {
* @throws IllegalArgumentException if preconditions are not met. * @throws IllegalArgumentException if preconditions are not met.
*/ */
public static double binomialCoefficientLog(final int n, final int k) { public static double binomialCoefficientLog(final int n, final int k) {
ArithmeticsUtils.checkBinomial(n, k); ArithmeticUtils.checkBinomial(n, k);
if ((n == k) || (k == 0)) { if ((n == k) || (k == 0)) {
return 0; return 0;
} }
@ -323,7 +323,7 @@ public final class ArithmeticsUtils {
if (n < 21) { if (n < 21) {
return factorial(n); return factorial(n);
} }
return FastMath.floor(FastMath.exp(ArithmeticsUtils.factorialLog(n)) + 0.5); return FastMath.floor(FastMath.exp(ArithmeticUtils.factorialLog(n)) + 0.5);
} }
/** /**
@ -548,7 +548,7 @@ public final class ArithmeticsUtils {
if (a == 0 || b == 0){ if (a == 0 || b == 0){
return 0; return 0;
} }
int lcm = FastMath.abs(ArithmeticsUtils.mulAndCheck(a / gcd(a, b), b)); int lcm = FastMath.abs(ArithmeticUtils.mulAndCheck(a / gcd(a, b), b));
if (lcm == Integer.MIN_VALUE) { if (lcm == Integer.MIN_VALUE) {
throw new MathArithmeticException(LocalizedFormats.LCM_OVERFLOW_32_BITS, throw new MathArithmeticException(LocalizedFormats.LCM_OVERFLOW_32_BITS,
a, b); a, b);
@ -582,7 +582,7 @@ public final class ArithmeticsUtils {
if (a == 0 || b == 0){ if (a == 0 || b == 0){
return 0; return 0;
} }
long lcm = FastMath.abs(ArithmeticsUtils.mulAndCheck(a / gcd(a, b), b)); long lcm = FastMath.abs(ArithmeticUtils.mulAndCheck(a / gcd(a, b), b));
if (lcm == Long.MIN_VALUE){ if (lcm == Long.MIN_VALUE){
throw new MathArithmeticException(LocalizedFormats.LCM_OVERFLOW_64_BITS, throw new MathArithmeticException(LocalizedFormats.LCM_OVERFLOW_64_BITS,
a, b); a, b);

View File

@ -18,7 +18,7 @@ package org.apache.commons.math.analysis.polynomials;
import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.analysis.integration.LegendreGaussIntegrator; import org.apache.commons.math.analysis.integration.LegendreGaussIntegrator;
import org.apache.commons.math.util.ArithmeticsUtils; import org.apache.commons.math.util.ArithmeticUtils;
import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.FastMath;
import org.apache.commons.math.util.Precision; import org.apache.commons.math.util.Precision;
import org.junit.Assert; import org.junit.Assert;
@ -289,7 +289,7 @@ public class PolynomialsUtilsTest {
for (int w = 0; w < 10; ++w) { for (int w = 0; w < 10; ++w) {
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
PolynomialFunction jacobi = PolynomialsUtils.createJacobiPolynomial(i, v, w); PolynomialFunction jacobi = PolynomialsUtils.createJacobiPolynomial(i, v, w);
double binomial = ArithmeticsUtils.binomialCoefficient(v + i, i); double binomial = ArithmeticUtils.binomialCoefficient(v + i, i);
Assert.assertTrue(Precision.equals(binomial, jacobi.value(1.0), 1)); Assert.assertTrue(Precision.equals(binomial, jacobi.value(1.0), 1));
} }
} }

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.linear; package org.apache.commons.math.linear;
import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.DimensionMismatchException;
import org.apache.commons.math.util.ArithmeticsUtils; import org.apache.commons.math.util.ArithmeticUtils;
/** /**
* This class implements inverses of Hilbert Matrices as * This class implements inverses of Hilbert Matrices as
@ -54,13 +54,13 @@ public class InverseHilbertMatrix
*/ */
public long getEntry(final int i, final int j) { public long getEntry(final int i, final int j) {
long val = i + j + 1; long val = i + j + 1;
long aux = ArithmeticsUtils.binomialCoefficient(n + i, n - j - 1); long aux = ArithmeticUtils.binomialCoefficient(n + i, n - j - 1);
val = ArithmeticsUtils.mulAndCheck(val, aux); val = ArithmeticUtils.mulAndCheck(val, aux);
aux = ArithmeticsUtils.binomialCoefficient(n + j, n - i - 1); aux = ArithmeticUtils.binomialCoefficient(n + j, n - i - 1);
val = ArithmeticsUtils.mulAndCheck(val, aux); val = ArithmeticUtils.mulAndCheck(val, aux);
aux = ArithmeticsUtils.binomialCoefficient(i + j, i); aux = ArithmeticUtils.binomialCoefficient(i + j, i);
val = ArithmeticsUtils.mulAndCheck(val, aux); val = ArithmeticUtils.mulAndCheck(val, aux);
val = ArithmeticsUtils.mulAndCheck(val, aux); val = ArithmeticUtils.mulAndCheck(val, aux);
return ((i + j) & 1) == 0 ? val : -val; return ((i + j) & 1) == 0 ? val : -val;
} }

View File

@ -28,11 +28,11 @@ import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
/** /**
* Test cases for the {@link ArithmeticsUtils} class. * Test cases for the {@link ArithmeticUtils} class.
* *
* @version $Id$ * @version $Id$
*/ */
public class ArithmeticsUtilsTest { public class ArithmeticUtilsTest {
/** cached binomial coefficients */ /** cached binomial coefficients */
private static final List<Map<Integer, Long>> binomialCache = new ArrayList<Map<Integer, Long>>(); private static final List<Map<Integer, Long>> binomialCache = new ArrayList<Map<Integer, Long>>();
@ -40,23 +40,23 @@ public class ArithmeticsUtilsTest {
/** Verify that b(0,0) = 1 */ /** Verify that b(0,0) = 1 */
@Test @Test
public void test0Choose0() { public void test0Choose0() {
Assert.assertEquals(ArithmeticsUtils.binomialCoefficientDouble(0, 0), 1d, 0); Assert.assertEquals(ArithmeticUtils.binomialCoefficientDouble(0, 0), 1d, 0);
Assert.assertEquals(ArithmeticsUtils.binomialCoefficientLog(0, 0), 0d, 0); Assert.assertEquals(ArithmeticUtils.binomialCoefficientLog(0, 0), 0d, 0);
Assert.assertEquals(ArithmeticsUtils.binomialCoefficient(0, 0), 1); Assert.assertEquals(ArithmeticUtils.binomialCoefficient(0, 0), 1);
} }
@Test @Test
public void testAddAndCheck() { public void testAddAndCheck() {
int big = Integer.MAX_VALUE; int big = Integer.MAX_VALUE;
int bigNeg = Integer.MIN_VALUE; int bigNeg = Integer.MIN_VALUE;
Assert.assertEquals(big, ArithmeticsUtils.addAndCheck(big, 0)); Assert.assertEquals(big, ArithmeticUtils.addAndCheck(big, 0));
try { try {
ArithmeticsUtils.addAndCheck(big, 1); ArithmeticUtils.addAndCheck(big, 1);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
} }
try { try {
ArithmeticsUtils.addAndCheck(bigNeg, -1); ArithmeticUtils.addAndCheck(bigNeg, -1);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
} }
@ -66,14 +66,14 @@ public class ArithmeticsUtilsTest {
public void testAddAndCheckLong() { public void testAddAndCheckLong() {
long max = Long.MAX_VALUE; long max = Long.MAX_VALUE;
long min = Long.MIN_VALUE; long min = Long.MIN_VALUE;
Assert.assertEquals(max, ArithmeticsUtils.addAndCheck(max, 0L)); Assert.assertEquals(max, ArithmeticUtils.addAndCheck(max, 0L));
Assert.assertEquals(min, ArithmeticsUtils.addAndCheck(min, 0L)); Assert.assertEquals(min, ArithmeticUtils.addAndCheck(min, 0L));
Assert.assertEquals(max, ArithmeticsUtils.addAndCheck(0L, max)); Assert.assertEquals(max, ArithmeticUtils.addAndCheck(0L, max));
Assert.assertEquals(min, ArithmeticsUtils.addAndCheck(0L, min)); Assert.assertEquals(min, ArithmeticUtils.addAndCheck(0L, min));
Assert.assertEquals(1, ArithmeticsUtils.addAndCheck(-1L, 2L)); Assert.assertEquals(1, ArithmeticUtils.addAndCheck(-1L, 2L));
Assert.assertEquals(1, ArithmeticsUtils.addAndCheck(2L, -1L)); Assert.assertEquals(1, ArithmeticUtils.addAndCheck(2L, -1L));
Assert.assertEquals(-3, ArithmeticsUtils.addAndCheck(-2L, -1L)); Assert.assertEquals(-3, ArithmeticUtils.addAndCheck(-2L, -1L));
Assert.assertEquals(min, ArithmeticsUtils.addAndCheck(min + 1, -1L)); Assert.assertEquals(min, ArithmeticUtils.addAndCheck(min + 1, -1L));
testAddAndCheckLongFailure(max, 1L); testAddAndCheckLongFailure(max, 1L);
testAddAndCheckLongFailure(min, -1L); testAddAndCheckLongFailure(min, -1L);
testAddAndCheckLongFailure(1L, max); testAddAndCheckLongFailure(1L, max);
@ -99,17 +99,17 @@ public class ArithmeticsUtilsTest {
6, 6,
1 }; 1 };
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
Assert.assertEquals("5 choose " + i, bcoef5[i], ArithmeticsUtils.binomialCoefficient(5, i)); Assert.assertEquals("5 choose " + i, bcoef5[i], ArithmeticUtils.binomialCoefficient(5, i));
} }
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
Assert.assertEquals("6 choose " + i, bcoef6[i], ArithmeticsUtils.binomialCoefficient(6, i)); Assert.assertEquals("6 choose " + i, bcoef6[i], ArithmeticUtils.binomialCoefficient(6, i));
} }
for (int n = 1; n < 10; n++) { for (int n = 1; n < 10; n++) {
for (int k = 0; k <= n; k++) { for (int k = 0; k <= n; k++) {
Assert.assertEquals(n + " choose " + k, binomialCoefficient(n, k), ArithmeticsUtils.binomialCoefficient(n, k)); Assert.assertEquals(n + " choose " + k, binomialCoefficient(n, k), ArithmeticUtils.binomialCoefficient(n, k));
Assert.assertEquals(n + " choose " + k, binomialCoefficient(n, k), ArithmeticsUtils.binomialCoefficientDouble(n, k), Double.MIN_VALUE); Assert.assertEquals(n + " choose " + k, binomialCoefficient(n, k), ArithmeticUtils.binomialCoefficientDouble(n, k), Double.MIN_VALUE);
Assert.assertEquals(n + " choose " + k, FastMath.log(binomialCoefficient(n, k)), ArithmeticsUtils.binomialCoefficientLog(n, k), 10E-12); Assert.assertEquals(n + " choose " + k, FastMath.log(binomialCoefficient(n, k)), ArithmeticUtils.binomialCoefficientLog(n, k), 10E-12);
} }
} }
@ -118,69 +118,69 @@ public class ArithmeticsUtilsTest {
for (int i = 0; i < n.length; i++) { for (int i = 0; i < n.length; i++) {
long expected = binomialCoefficient(n[i], k[i]); long expected = binomialCoefficient(n[i], k[i]);
Assert.assertEquals(n[i] + " choose " + k[i], expected, Assert.assertEquals(n[i] + " choose " + k[i], expected,
ArithmeticsUtils.binomialCoefficient(n[i], k[i])); ArithmeticUtils.binomialCoefficient(n[i], k[i]));
Assert.assertEquals(n[i] + " choose " + k[i], expected, Assert.assertEquals(n[i] + " choose " + k[i], expected,
ArithmeticsUtils.binomialCoefficientDouble(n[i], k[i]), 0.0); ArithmeticUtils.binomialCoefficientDouble(n[i], k[i]), 0.0);
Assert.assertEquals("log(" + n[i] + " choose " + k[i] + ")", FastMath.log(expected), Assert.assertEquals("log(" + n[i] + " choose " + k[i] + ")", FastMath.log(expected),
ArithmeticsUtils.binomialCoefficientLog(n[i], k[i]), 0.0); ArithmeticUtils.binomialCoefficientLog(n[i], k[i]), 0.0);
} }
} }
@Test @Test
public void testBinomialCoefficientFail() { public void testBinomialCoefficientFail() {
try { try {
ArithmeticsUtils.binomialCoefficient(4, 5); ArithmeticUtils.binomialCoefficient(4, 5);
Assert.fail("expecting MathIllegalArgumentException"); Assert.fail("expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException ex) { } catch (MathIllegalArgumentException ex) {
// ignored // ignored
} }
try { try {
ArithmeticsUtils.binomialCoefficientDouble(4, 5); ArithmeticUtils.binomialCoefficientDouble(4, 5);
Assert.fail("expecting MathIllegalArgumentException"); Assert.fail("expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException ex) { } catch (MathIllegalArgumentException ex) {
// ignored // ignored
} }
try { try {
ArithmeticsUtils.binomialCoefficientLog(4, 5); ArithmeticUtils.binomialCoefficientLog(4, 5);
Assert.fail("expecting MathIllegalArgumentException"); Assert.fail("expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException ex) { } catch (MathIllegalArgumentException ex) {
// ignored // ignored
} }
try { try {
ArithmeticsUtils.binomialCoefficient(-1, -2); ArithmeticUtils.binomialCoefficient(-1, -2);
Assert.fail("expecting MathIllegalArgumentException"); Assert.fail("expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException ex) { } catch (MathIllegalArgumentException ex) {
// ignored // ignored
} }
try { try {
ArithmeticsUtils.binomialCoefficientDouble(-1, -2); ArithmeticUtils.binomialCoefficientDouble(-1, -2);
Assert.fail("expecting MathIllegalArgumentException"); Assert.fail("expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException ex) { } catch (MathIllegalArgumentException ex) {
// ignored // ignored
} }
try { try {
ArithmeticsUtils.binomialCoefficientLog(-1, -2); ArithmeticUtils.binomialCoefficientLog(-1, -2);
Assert.fail("expecting MathIllegalArgumentException"); Assert.fail("expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException ex) { } catch (MathIllegalArgumentException ex) {
// ignored // ignored
} }
try { try {
ArithmeticsUtils.binomialCoefficient(67, 30); ArithmeticUtils.binomialCoefficient(67, 30);
Assert.fail("expecting MathArithmeticException"); Assert.fail("expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
// ignored // ignored
} }
try { try {
ArithmeticsUtils.binomialCoefficient(67, 34); ArithmeticUtils.binomialCoefficient(67, 34);
Assert.fail("expecting MathArithmeticException"); Assert.fail("expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
// ignored // ignored
} }
double x = ArithmeticsUtils.binomialCoefficientDouble(1030, 515); double x = ArithmeticUtils.binomialCoefficientDouble(1030, 515);
Assert.assertTrue("expecting infinite binomial coefficient", Double Assert.assertTrue("expecting infinite binomial coefficient", Double
.isInfinite(x)); .isInfinite(x));
} }
@ -199,7 +199,7 @@ public class ArithmeticsUtilsTest {
boolean shouldThrow = false; boolean shouldThrow = false;
boolean didThrow = false; boolean didThrow = false;
try { try {
ourResult = ArithmeticsUtils.binomialCoefficient(n, k); ourResult = ArithmeticUtils.binomialCoefficient(n, k);
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
didThrow = true; didThrow = true;
} }
@ -214,78 +214,78 @@ public class ArithmeticsUtilsTest {
if (!shouldThrow && exactResult > 1) { if (!shouldThrow && exactResult > 1) {
Assert.assertEquals(n + " choose " + k, 1., Assert.assertEquals(n + " choose " + k, 1.,
ArithmeticsUtils.binomialCoefficientDouble(n, k) / exactResult, 1e-10); ArithmeticUtils.binomialCoefficientDouble(n, k) / exactResult, 1e-10);
Assert.assertEquals(n + " choose " + k, 1, Assert.assertEquals(n + " choose " + k, 1,
ArithmeticsUtils.binomialCoefficientLog(n, k) / FastMath.log(exactResult), 1e-10); ArithmeticUtils.binomialCoefficientLog(n, k) / FastMath.log(exactResult), 1e-10);
} }
} }
} }
long ourResult = ArithmeticsUtils.binomialCoefficient(300, 3); long ourResult = ArithmeticUtils.binomialCoefficient(300, 3);
long exactResult = binomialCoefficient(300, 3); long exactResult = binomialCoefficient(300, 3);
Assert.assertEquals(exactResult, ourResult); Assert.assertEquals(exactResult, ourResult);
ourResult = ArithmeticsUtils.binomialCoefficient(700, 697); ourResult = ArithmeticUtils.binomialCoefficient(700, 697);
exactResult = binomialCoefficient(700, 697); exactResult = binomialCoefficient(700, 697);
Assert.assertEquals(exactResult, ourResult); Assert.assertEquals(exactResult, ourResult);
// This one should throw // This one should throw
try { try {
ArithmeticsUtils.binomialCoefficient(700, 300); ArithmeticUtils.binomialCoefficient(700, 300);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
// Expected // Expected
} }
int n = 10000; int n = 10000;
ourResult = ArithmeticsUtils.binomialCoefficient(n, 3); ourResult = ArithmeticUtils.binomialCoefficient(n, 3);
exactResult = binomialCoefficient(n, 3); exactResult = binomialCoefficient(n, 3);
Assert.assertEquals(exactResult, ourResult); Assert.assertEquals(exactResult, ourResult);
Assert.assertEquals(1, ArithmeticsUtils.binomialCoefficientDouble(n, 3) / exactResult, 1e-10); Assert.assertEquals(1, ArithmeticUtils.binomialCoefficientDouble(n, 3) / exactResult, 1e-10);
Assert.assertEquals(1, ArithmeticsUtils.binomialCoefficientLog(n, 3) / FastMath.log(exactResult), 1e-10); Assert.assertEquals(1, ArithmeticUtils.binomialCoefficientLog(n, 3) / FastMath.log(exactResult), 1e-10);
} }
@Test @Test
public void testFactorial() { public void testFactorial() {
for (int i = 1; i < 21; i++) { for (int i = 1; i < 21; i++) {
Assert.assertEquals(i + "! ", factorial(i), ArithmeticsUtils.factorial(i)); Assert.assertEquals(i + "! ", factorial(i), ArithmeticUtils.factorial(i));
Assert.assertEquals(i + "! ", factorial(i), ArithmeticsUtils.factorialDouble(i), Double.MIN_VALUE); Assert.assertEquals(i + "! ", factorial(i), ArithmeticUtils.factorialDouble(i), Double.MIN_VALUE);
Assert.assertEquals(i + "! ", FastMath.log(factorial(i)), ArithmeticsUtils.factorialLog(i), 10E-12); Assert.assertEquals(i + "! ", FastMath.log(factorial(i)), ArithmeticUtils.factorialLog(i), 10E-12);
} }
Assert.assertEquals("0", 1, ArithmeticsUtils.factorial(0)); Assert.assertEquals("0", 1, ArithmeticUtils.factorial(0));
Assert.assertEquals("0", 1.0d, ArithmeticsUtils.factorialDouble(0), 1E-14); Assert.assertEquals("0", 1.0d, ArithmeticUtils.factorialDouble(0), 1E-14);
Assert.assertEquals("0", 0.0d, ArithmeticsUtils.factorialLog(0), 1E-14); Assert.assertEquals("0", 0.0d, ArithmeticUtils.factorialLog(0), 1E-14);
} }
@Test @Test
public void testFactorialFail() { public void testFactorialFail() {
try { try {
ArithmeticsUtils.factorial(-1); ArithmeticUtils.factorial(-1);
Assert.fail("expecting MathIllegalArgumentException"); Assert.fail("expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException ex) { } catch (MathIllegalArgumentException ex) {
// ignored // ignored
} }
try { try {
ArithmeticsUtils.factorialDouble(-1); ArithmeticUtils.factorialDouble(-1);
Assert.fail("expecting MathIllegalArgumentException"); Assert.fail("expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException ex) { } catch (MathIllegalArgumentException ex) {
// ignored // ignored
} }
try { try {
ArithmeticsUtils.factorialLog(-1); ArithmeticUtils.factorialLog(-1);
Assert.fail("expecting MathIllegalArgumentException"); Assert.fail("expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException ex) { } catch (MathIllegalArgumentException ex) {
// ignored // ignored
} }
try { try {
ArithmeticsUtils.factorial(21); ArithmeticUtils.factorial(21);
Assert.fail("expecting MathArithmeticException"); Assert.fail("expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
// ignored // ignored
} }
Assert.assertTrue("expecting infinite factorial value", Double.isInfinite(ArithmeticsUtils.factorialDouble(171))); Assert.assertTrue("expecting infinite factorial value", Double.isInfinite(ArithmeticUtils.factorialDouble(171)));
} }
@Test @Test
@ -294,45 +294,45 @@ public class ArithmeticsUtilsTest {
int b = 50; int b = 50;
int c = 77; int c = 77;
Assert.assertEquals(0, ArithmeticsUtils.gcd(0, 0)); Assert.assertEquals(0, ArithmeticUtils.gcd(0, 0));
Assert.assertEquals(b, ArithmeticsUtils.gcd(0, b)); Assert.assertEquals(b, ArithmeticUtils.gcd(0, b));
Assert.assertEquals(a, ArithmeticsUtils.gcd(a, 0)); Assert.assertEquals(a, ArithmeticUtils.gcd(a, 0));
Assert.assertEquals(b, ArithmeticsUtils.gcd(0, -b)); Assert.assertEquals(b, ArithmeticUtils.gcd(0, -b));
Assert.assertEquals(a, ArithmeticsUtils.gcd(-a, 0)); Assert.assertEquals(a, ArithmeticUtils.gcd(-a, 0));
Assert.assertEquals(10, ArithmeticsUtils.gcd(a, b)); Assert.assertEquals(10, ArithmeticUtils.gcd(a, b));
Assert.assertEquals(10, ArithmeticsUtils.gcd(-a, b)); Assert.assertEquals(10, ArithmeticUtils.gcd(-a, b));
Assert.assertEquals(10, ArithmeticsUtils.gcd(a, -b)); Assert.assertEquals(10, ArithmeticUtils.gcd(a, -b));
Assert.assertEquals(10, ArithmeticsUtils.gcd(-a, -b)); Assert.assertEquals(10, ArithmeticUtils.gcd(-a, -b));
Assert.assertEquals(1, ArithmeticsUtils.gcd(a, c)); Assert.assertEquals(1, ArithmeticUtils.gcd(a, c));
Assert.assertEquals(1, ArithmeticsUtils.gcd(-a, c)); Assert.assertEquals(1, ArithmeticUtils.gcd(-a, c));
Assert.assertEquals(1, ArithmeticsUtils.gcd(a, -c)); Assert.assertEquals(1, ArithmeticUtils.gcd(a, -c));
Assert.assertEquals(1, ArithmeticsUtils.gcd(-a, -c)); Assert.assertEquals(1, ArithmeticUtils.gcd(-a, -c));
Assert.assertEquals(3 * (1<<15), ArithmeticsUtils.gcd(3 * (1<<20), 9 * (1<<15))); Assert.assertEquals(3 * (1<<15), ArithmeticUtils.gcd(3 * (1<<20), 9 * (1<<15)));
Assert.assertEquals(Integer.MAX_VALUE, ArithmeticsUtils.gcd(Integer.MAX_VALUE, 0)); Assert.assertEquals(Integer.MAX_VALUE, ArithmeticUtils.gcd(Integer.MAX_VALUE, 0));
Assert.assertEquals(Integer.MAX_VALUE, ArithmeticsUtils.gcd(-Integer.MAX_VALUE, 0)); Assert.assertEquals(Integer.MAX_VALUE, ArithmeticUtils.gcd(-Integer.MAX_VALUE, 0));
Assert.assertEquals(1<<30, ArithmeticsUtils.gcd(1<<30, -Integer.MIN_VALUE)); Assert.assertEquals(1<<30, ArithmeticUtils.gcd(1<<30, -Integer.MIN_VALUE));
try { try {
// gcd(Integer.MIN_VALUE, 0) > Integer.MAX_VALUE // gcd(Integer.MIN_VALUE, 0) > Integer.MAX_VALUE
ArithmeticsUtils.gcd(Integer.MIN_VALUE, 0); ArithmeticUtils.gcd(Integer.MIN_VALUE, 0);
Assert.fail("expecting MathArithmeticException"); Assert.fail("expecting MathArithmeticException");
} catch (MathArithmeticException expected) { } catch (MathArithmeticException expected) {
// expected // expected
} }
try { try {
// gcd(0, Integer.MIN_VALUE) > Integer.MAX_VALUE // gcd(0, Integer.MIN_VALUE) > Integer.MAX_VALUE
ArithmeticsUtils.gcd(0, Integer.MIN_VALUE); ArithmeticUtils.gcd(0, Integer.MIN_VALUE);
Assert.fail("expecting MathArithmeticException"); Assert.fail("expecting MathArithmeticException");
} catch (MathArithmeticException expected) { } catch (MathArithmeticException expected) {
// expected // expected
} }
try { try {
// gcd(Integer.MIN_VALUE, Integer.MIN_VALUE) > Integer.MAX_VALUE // gcd(Integer.MIN_VALUE, Integer.MIN_VALUE) > Integer.MAX_VALUE
ArithmeticsUtils.gcd(Integer.MIN_VALUE, Integer.MIN_VALUE); ArithmeticUtils.gcd(Integer.MIN_VALUE, Integer.MIN_VALUE);
Assert.fail("expecting MathArithmeticException"); Assert.fail("expecting MathArithmeticException");
} catch (MathArithmeticException expected) { } catch (MathArithmeticException expected) {
// expected // expected
@ -356,10 +356,10 @@ public class ArithmeticsUtilsTest {
int i1 = p1 * p2 * p3; int i1 = p1 * p2 * p3;
int i2 = p1 * p2 * p4; int i2 = p1 * p2 * p4;
int gcd = p1 * p2; int gcd = p1 * p2;
Assert.assertEquals(gcd, ArithmeticsUtils.gcd(i1, i2)); Assert.assertEquals(gcd, ArithmeticUtils.gcd(i1, i2));
long l1 = i1; long l1 = i1;
long l2 = i2; long l2 = i2;
Assert.assertEquals(gcd, ArithmeticsUtils.gcd(l1, l2)); Assert.assertEquals(gcd, ArithmeticUtils.gcd(l1, l2));
} }
} }
@ -369,47 +369,47 @@ public class ArithmeticsUtilsTest {
long b = 50; long b = 50;
long c = 77; long c = 77;
Assert.assertEquals(0, ArithmeticsUtils.gcd(0L, 0)); Assert.assertEquals(0, ArithmeticUtils.gcd(0L, 0));
Assert.assertEquals(b, ArithmeticsUtils.gcd(0, b)); Assert.assertEquals(b, ArithmeticUtils.gcd(0, b));
Assert.assertEquals(a, ArithmeticsUtils.gcd(a, 0)); Assert.assertEquals(a, ArithmeticUtils.gcd(a, 0));
Assert.assertEquals(b, ArithmeticsUtils.gcd(0, -b)); Assert.assertEquals(b, ArithmeticUtils.gcd(0, -b));
Assert.assertEquals(a, ArithmeticsUtils.gcd(-a, 0)); Assert.assertEquals(a, ArithmeticUtils.gcd(-a, 0));
Assert.assertEquals(10, ArithmeticsUtils.gcd(a, b)); Assert.assertEquals(10, ArithmeticUtils.gcd(a, b));
Assert.assertEquals(10, ArithmeticsUtils.gcd(-a, b)); Assert.assertEquals(10, ArithmeticUtils.gcd(-a, b));
Assert.assertEquals(10, ArithmeticsUtils.gcd(a, -b)); Assert.assertEquals(10, ArithmeticUtils.gcd(a, -b));
Assert.assertEquals(10, ArithmeticsUtils.gcd(-a, -b)); Assert.assertEquals(10, ArithmeticUtils.gcd(-a, -b));
Assert.assertEquals(1, ArithmeticsUtils.gcd(a, c)); Assert.assertEquals(1, ArithmeticUtils.gcd(a, c));
Assert.assertEquals(1, ArithmeticsUtils.gcd(-a, c)); Assert.assertEquals(1, ArithmeticUtils.gcd(-a, c));
Assert.assertEquals(1, ArithmeticsUtils.gcd(a, -c)); Assert.assertEquals(1, ArithmeticUtils.gcd(a, -c));
Assert.assertEquals(1, ArithmeticsUtils.gcd(-a, -c)); Assert.assertEquals(1, ArithmeticUtils.gcd(-a, -c));
Assert.assertEquals(3L * (1L<<45), ArithmeticsUtils.gcd(3L * (1L<<50), 9L * (1L<<45))); Assert.assertEquals(3L * (1L<<45), ArithmeticUtils.gcd(3L * (1L<<50), 9L * (1L<<45)));
Assert.assertEquals(1L<<45, ArithmeticsUtils.gcd(1L<<45, Long.MIN_VALUE)); Assert.assertEquals(1L<<45, ArithmeticUtils.gcd(1L<<45, Long.MIN_VALUE));
Assert.assertEquals(Long.MAX_VALUE, ArithmeticsUtils.gcd(Long.MAX_VALUE, 0L)); Assert.assertEquals(Long.MAX_VALUE, ArithmeticUtils.gcd(Long.MAX_VALUE, 0L));
Assert.assertEquals(Long.MAX_VALUE, ArithmeticsUtils.gcd(-Long.MAX_VALUE, 0L)); Assert.assertEquals(Long.MAX_VALUE, ArithmeticUtils.gcd(-Long.MAX_VALUE, 0L));
Assert.assertEquals(1, ArithmeticsUtils.gcd(60247241209L, 153092023L)); Assert.assertEquals(1, ArithmeticUtils.gcd(60247241209L, 153092023L));
try { try {
// gcd(Long.MIN_VALUE, 0) > Long.MAX_VALUE // gcd(Long.MIN_VALUE, 0) > Long.MAX_VALUE
ArithmeticsUtils.gcd(Long.MIN_VALUE, 0); ArithmeticUtils.gcd(Long.MIN_VALUE, 0);
Assert.fail("expecting MathArithmeticException"); Assert.fail("expecting MathArithmeticException");
} catch (MathArithmeticException expected) { } catch (MathArithmeticException expected) {
// expected // expected
} }
try { try {
// gcd(0, Long.MIN_VALUE) > Long.MAX_VALUE // gcd(0, Long.MIN_VALUE) > Long.MAX_VALUE
ArithmeticsUtils.gcd(0, Long.MIN_VALUE); ArithmeticUtils.gcd(0, Long.MIN_VALUE);
Assert.fail("expecting MathArithmeticException"); Assert.fail("expecting MathArithmeticException");
} catch (MathArithmeticException expected) { } catch (MathArithmeticException expected) {
// expected // expected
} }
try { try {
// gcd(Long.MIN_VALUE, Long.MIN_VALUE) > Long.MAX_VALUE // gcd(Long.MIN_VALUE, Long.MIN_VALUE) > Long.MAX_VALUE
ArithmeticsUtils.gcd(Long.MIN_VALUE, Long.MIN_VALUE); ArithmeticUtils.gcd(Long.MIN_VALUE, Long.MIN_VALUE);
Assert.fail("expecting MathArithmeticException"); Assert.fail("expecting MathArithmeticException");
} catch (MathArithmeticException expected) { } catch (MathArithmeticException expected) {
// expected // expected
@ -423,26 +423,26 @@ public class ArithmeticsUtilsTest {
int b = 50; int b = 50;
int c = 77; int c = 77;
Assert.assertEquals(0, ArithmeticsUtils.lcm(0, b)); Assert.assertEquals(0, ArithmeticUtils.lcm(0, b));
Assert.assertEquals(0, ArithmeticsUtils.lcm(a, 0)); Assert.assertEquals(0, ArithmeticUtils.lcm(a, 0));
Assert.assertEquals(b, ArithmeticsUtils.lcm(1, b)); Assert.assertEquals(b, ArithmeticUtils.lcm(1, b));
Assert.assertEquals(a, ArithmeticsUtils.lcm(a, 1)); Assert.assertEquals(a, ArithmeticUtils.lcm(a, 1));
Assert.assertEquals(150, ArithmeticsUtils.lcm(a, b)); Assert.assertEquals(150, ArithmeticUtils.lcm(a, b));
Assert.assertEquals(150, ArithmeticsUtils.lcm(-a, b)); Assert.assertEquals(150, ArithmeticUtils.lcm(-a, b));
Assert.assertEquals(150, ArithmeticsUtils.lcm(a, -b)); Assert.assertEquals(150, ArithmeticUtils.lcm(a, -b));
Assert.assertEquals(150, ArithmeticsUtils.lcm(-a, -b)); Assert.assertEquals(150, ArithmeticUtils.lcm(-a, -b));
Assert.assertEquals(2310, ArithmeticsUtils.lcm(a, c)); Assert.assertEquals(2310, ArithmeticUtils.lcm(a, c));
// Assert that no intermediate value overflows: // Assert that no intermediate value overflows:
// The naive implementation of lcm(a,b) would be (a*b)/gcd(a,b) // The naive implementation of lcm(a,b) would be (a*b)/gcd(a,b)
Assert.assertEquals((1<<20)*15, ArithmeticsUtils.lcm((1<<20)*3, (1<<20)*5)); Assert.assertEquals((1<<20)*15, ArithmeticUtils.lcm((1<<20)*3, (1<<20)*5));
// Special case // Special case
Assert.assertEquals(0, ArithmeticsUtils.lcm(0, 0)); Assert.assertEquals(0, ArithmeticUtils.lcm(0, 0));
try { try {
// lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int
ArithmeticsUtils.lcm(Integer.MIN_VALUE, 1); ArithmeticUtils.lcm(Integer.MIN_VALUE, 1);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException expected) { } catch (MathArithmeticException expected) {
// expected // expected
@ -450,14 +450,14 @@ public class ArithmeticsUtilsTest {
try { try {
// lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int
ArithmeticsUtils.lcm(Integer.MIN_VALUE, 1<<20); ArithmeticUtils.lcm(Integer.MIN_VALUE, 1<<20);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException expected) { } catch (MathArithmeticException expected) {
// expected // expected
} }
try { try {
ArithmeticsUtils.lcm(Integer.MAX_VALUE, Integer.MAX_VALUE - 1); ArithmeticUtils.lcm(Integer.MAX_VALUE, Integer.MAX_VALUE - 1);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException expected) { } catch (MathArithmeticException expected) {
// expected // expected
@ -470,28 +470,28 @@ public class ArithmeticsUtilsTest {
long b = 50; long b = 50;
long c = 77; long c = 77;
Assert.assertEquals(0, ArithmeticsUtils.lcm(0, b)); Assert.assertEquals(0, ArithmeticUtils.lcm(0, b));
Assert.assertEquals(0, ArithmeticsUtils.lcm(a, 0)); Assert.assertEquals(0, ArithmeticUtils.lcm(a, 0));
Assert.assertEquals(b, ArithmeticsUtils.lcm(1, b)); Assert.assertEquals(b, ArithmeticUtils.lcm(1, b));
Assert.assertEquals(a, ArithmeticsUtils.lcm(a, 1)); Assert.assertEquals(a, ArithmeticUtils.lcm(a, 1));
Assert.assertEquals(150, ArithmeticsUtils.lcm(a, b)); Assert.assertEquals(150, ArithmeticUtils.lcm(a, b));
Assert.assertEquals(150, ArithmeticsUtils.lcm(-a, b)); Assert.assertEquals(150, ArithmeticUtils.lcm(-a, b));
Assert.assertEquals(150, ArithmeticsUtils.lcm(a, -b)); Assert.assertEquals(150, ArithmeticUtils.lcm(a, -b));
Assert.assertEquals(150, ArithmeticsUtils.lcm(-a, -b)); Assert.assertEquals(150, ArithmeticUtils.lcm(-a, -b));
Assert.assertEquals(2310, ArithmeticsUtils.lcm(a, c)); Assert.assertEquals(2310, ArithmeticUtils.lcm(a, c));
Assert.assertEquals(Long.MAX_VALUE, ArithmeticsUtils.lcm(60247241209L, 153092023L)); Assert.assertEquals(Long.MAX_VALUE, ArithmeticUtils.lcm(60247241209L, 153092023L));
// Assert that no intermediate value overflows: // Assert that no intermediate value overflows:
// The naive implementation of lcm(a,b) would be (a*b)/gcd(a,b) // The naive implementation of lcm(a,b) would be (a*b)/gcd(a,b)
Assert.assertEquals((1L<<50)*15, ArithmeticsUtils.lcm((1L<<45)*3, (1L<<50)*5)); Assert.assertEquals((1L<<50)*15, ArithmeticUtils.lcm((1L<<45)*3, (1L<<50)*5));
// Special case // Special case
Assert.assertEquals(0L, ArithmeticsUtils.lcm(0L, 0L)); Assert.assertEquals(0L, ArithmeticUtils.lcm(0L, 0L));
try { try {
// lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int
ArithmeticsUtils.lcm(Long.MIN_VALUE, 1); ArithmeticUtils.lcm(Long.MIN_VALUE, 1);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException expected) { } catch (MathArithmeticException expected) {
// expected // expected
@ -499,16 +499,16 @@ public class ArithmeticsUtilsTest {
try { try {
// lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int
ArithmeticsUtils.lcm(Long.MIN_VALUE, 1<<20); ArithmeticUtils.lcm(Long.MIN_VALUE, 1<<20);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException expected) { } catch (MathArithmeticException expected) {
// expected // expected
} }
Assert.assertEquals((long) Integer.MAX_VALUE * (Integer.MAX_VALUE - 1), Assert.assertEquals((long) Integer.MAX_VALUE * (Integer.MAX_VALUE - 1),
ArithmeticsUtils.lcm((long)Integer.MAX_VALUE, Integer.MAX_VALUE - 1)); ArithmeticUtils.lcm((long)Integer.MAX_VALUE, Integer.MAX_VALUE - 1));
try { try {
ArithmeticsUtils.lcm(Long.MAX_VALUE, Long.MAX_VALUE - 1); ArithmeticUtils.lcm(Long.MAX_VALUE, Long.MAX_VALUE - 1);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException expected) { } catch (MathArithmeticException expected) {
// expected // expected
@ -519,14 +519,14 @@ public class ArithmeticsUtilsTest {
public void testMulAndCheck() { public void testMulAndCheck() {
int big = Integer.MAX_VALUE; int big = Integer.MAX_VALUE;
int bigNeg = Integer.MIN_VALUE; int bigNeg = Integer.MIN_VALUE;
Assert.assertEquals(big, ArithmeticsUtils.mulAndCheck(big, 1)); Assert.assertEquals(big, ArithmeticUtils.mulAndCheck(big, 1));
try { try {
ArithmeticsUtils.mulAndCheck(big, 2); ArithmeticUtils.mulAndCheck(big, 2);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
} }
try { try {
ArithmeticsUtils.mulAndCheck(bigNeg, 2); ArithmeticUtils.mulAndCheck(bigNeg, 2);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
} }
@ -536,16 +536,16 @@ public class ArithmeticsUtilsTest {
public void testMulAndCheckLong() { public void testMulAndCheckLong() {
long max = Long.MAX_VALUE; long max = Long.MAX_VALUE;
long min = Long.MIN_VALUE; long min = Long.MIN_VALUE;
Assert.assertEquals(max, ArithmeticsUtils.mulAndCheck(max, 1L)); Assert.assertEquals(max, ArithmeticUtils.mulAndCheck(max, 1L));
Assert.assertEquals(min, ArithmeticsUtils.mulAndCheck(min, 1L)); Assert.assertEquals(min, ArithmeticUtils.mulAndCheck(min, 1L));
Assert.assertEquals(0L, ArithmeticsUtils.mulAndCheck(max, 0L)); Assert.assertEquals(0L, ArithmeticUtils.mulAndCheck(max, 0L));
Assert.assertEquals(0L, ArithmeticsUtils.mulAndCheck(min, 0L)); Assert.assertEquals(0L, ArithmeticUtils.mulAndCheck(min, 0L));
Assert.assertEquals(max, ArithmeticsUtils.mulAndCheck(1L, max)); Assert.assertEquals(max, ArithmeticUtils.mulAndCheck(1L, max));
Assert.assertEquals(min, ArithmeticsUtils.mulAndCheck(1L, min)); Assert.assertEquals(min, ArithmeticUtils.mulAndCheck(1L, min));
Assert.assertEquals(0L, ArithmeticsUtils.mulAndCheck(0L, max)); Assert.assertEquals(0L, ArithmeticUtils.mulAndCheck(0L, max));
Assert.assertEquals(0L, ArithmeticsUtils.mulAndCheck(0L, min)); Assert.assertEquals(0L, ArithmeticUtils.mulAndCheck(0L, min));
Assert.assertEquals(1L, ArithmeticsUtils.mulAndCheck(-1L, -1L)); Assert.assertEquals(1L, ArithmeticUtils.mulAndCheck(-1L, -1L));
Assert.assertEquals(min, ArithmeticsUtils.mulAndCheck(min / 2, 2)); Assert.assertEquals(min, ArithmeticUtils.mulAndCheck(min / 2, 2));
testMulAndCheckLongFailure(max, 2L); testMulAndCheckLongFailure(max, 2L);
testMulAndCheckLongFailure(2L, max); testMulAndCheckLongFailure(2L, max);
testMulAndCheckLongFailure(min, 2L); testMulAndCheckLongFailure(min, 2L);
@ -558,16 +558,16 @@ public class ArithmeticsUtilsTest {
public void testSubAndCheck() { public void testSubAndCheck() {
int big = Integer.MAX_VALUE; int big = Integer.MAX_VALUE;
int bigNeg = Integer.MIN_VALUE; int bigNeg = Integer.MIN_VALUE;
Assert.assertEquals(big, ArithmeticsUtils.subAndCheck(big, 0)); Assert.assertEquals(big, ArithmeticUtils.subAndCheck(big, 0));
Assert.assertEquals(bigNeg + 1, ArithmeticsUtils.subAndCheck(bigNeg, -1)); Assert.assertEquals(bigNeg + 1, ArithmeticUtils.subAndCheck(bigNeg, -1));
Assert.assertEquals(-1, ArithmeticsUtils.subAndCheck(bigNeg, -big)); Assert.assertEquals(-1, ArithmeticUtils.subAndCheck(bigNeg, -big));
try { try {
ArithmeticsUtils.subAndCheck(big, -1); ArithmeticUtils.subAndCheck(big, -1);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
} }
try { try {
ArithmeticsUtils.subAndCheck(bigNeg, 1); ArithmeticUtils.subAndCheck(bigNeg, 1);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
} }
@ -577,7 +577,7 @@ public class ArithmeticsUtilsTest {
public void testSubAndCheckErrorMessage() { public void testSubAndCheckErrorMessage() {
int big = Integer.MAX_VALUE; int big = Integer.MAX_VALUE;
try { try {
ArithmeticsUtils.subAndCheck(big, -1); ArithmeticUtils.subAndCheck(big, -1);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
Assert.assertTrue(ex.getMessage().length() > 1); Assert.assertTrue(ex.getMessage().length() > 1);
@ -588,13 +588,13 @@ public class ArithmeticsUtilsTest {
public void testSubAndCheckLong() { public void testSubAndCheckLong() {
long max = Long.MAX_VALUE; long max = Long.MAX_VALUE;
long min = Long.MIN_VALUE; long min = Long.MIN_VALUE;
Assert.assertEquals(max, ArithmeticsUtils.subAndCheck(max, 0)); Assert.assertEquals(max, ArithmeticUtils.subAndCheck(max, 0));
Assert.assertEquals(min, ArithmeticsUtils.subAndCheck(min, 0)); Assert.assertEquals(min, ArithmeticUtils.subAndCheck(min, 0));
Assert.assertEquals(-max, ArithmeticsUtils.subAndCheck(0, max)); Assert.assertEquals(-max, ArithmeticUtils.subAndCheck(0, max));
Assert.assertEquals(min + 1, ArithmeticsUtils.subAndCheck(min, -1)); Assert.assertEquals(min + 1, ArithmeticUtils.subAndCheck(min, -1));
// min == -1-max // min == -1-max
Assert.assertEquals(-1, ArithmeticsUtils.subAndCheck(-max - 1, -max)); Assert.assertEquals(-1, ArithmeticUtils.subAndCheck(-max - 1, -max));
Assert.assertEquals(max, ArithmeticsUtils.subAndCheck(-1, -1 - max)); Assert.assertEquals(max, ArithmeticUtils.subAndCheck(-1, -1 - max));
testSubAndCheckLongFailure(0L, min); testSubAndCheckLongFailure(0L, min);
testSubAndCheckLongFailure(max, -1L); testSubAndCheckLongFailure(max, -1L);
testSubAndCheckLongFailure(min, 1L); testSubAndCheckLongFailure(min, 1L);
@ -623,7 +623,7 @@ public class ArithmeticsUtilsTest {
if (k > 100) { if (k > 100) {
binomialCoefficient(n - 100, k - 100); binomialCoefficient(n - 100, k - 100);
} }
result = ArithmeticsUtils.addAndCheck(binomialCoefficient(n - 1, k - 1), result = ArithmeticUtils.addAndCheck(binomialCoefficient(n - 1, k - 1),
binomialCoefficient(n - 1, k)); binomialCoefficient(n - 1, k));
} }
if (result == -1) { if (result == -1) {
@ -649,7 +649,7 @@ public class ArithmeticsUtilsTest {
private void testAddAndCheckLongFailure(long a, long b) { private void testAddAndCheckLongFailure(long a, long b) {
try { try {
ArithmeticsUtils.addAndCheck(a, b); ArithmeticUtils.addAndCheck(a, b);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
// success // success
@ -658,7 +658,7 @@ public class ArithmeticsUtilsTest {
private void testMulAndCheckLongFailure(long a, long b) { private void testMulAndCheckLongFailure(long a, long b) {
try { try {
ArithmeticsUtils.mulAndCheck(a, b); ArithmeticUtils.mulAndCheck(a, b);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
// success // success
@ -667,7 +667,7 @@ public class ArithmeticsUtilsTest {
private void testSubAndCheckLongFailure(long a, long b) { private void testSubAndCheckLongFailure(long a, long b) {
try { try {
ArithmeticsUtils.subAndCheck(a, b); ArithmeticUtils.subAndCheck(a, b);
Assert.fail("Expecting MathArithmeticException"); Assert.fail("Expecting MathArithmeticException");
} catch (MathArithmeticException ex) { } catch (MathArithmeticException ex) {
// success // success