Moved "pow" (integer arguments) to "ArithmeticUtils".


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1206199 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Gilles Sadowski 2011-11-25 14:48:54 +00:00
parent 80ddc491f1
commit ec5d9d3772
5 changed files with 261 additions and 263 deletions

View File

@ -27,6 +27,7 @@ import org.apache.commons.math.exception.ZeroException;
import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.util.FastMath; import org.apache.commons.math.util.FastMath;
import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.MathUtils;
import org.apache.commons.math.util.ArithmeticUtils;
/** /**
* Representation of a rational number without any overflow. This class is * Representation of a rational number without any overflow. This class is
@ -956,11 +957,11 @@ public class BigFraction
*/ */
public BigFraction pow(final long exponent) { public BigFraction pow(final long exponent) {
if (exponent < 0) { if (exponent < 0) {
return new BigFraction(MathUtils.pow(denominator, -exponent), return new BigFraction(ArithmeticUtils.pow(denominator, -exponent),
MathUtils.pow(numerator, -exponent)); ArithmeticUtils.pow(numerator, -exponent));
} }
return new BigFraction(MathUtils.pow(numerator, exponent), return new BigFraction(ArithmeticUtils.pow(numerator, exponent),
MathUtils.pow(denominator, exponent)); ArithmeticUtils.pow(denominator, exponent));
} }
/** /**
@ -976,11 +977,11 @@ public class BigFraction
public BigFraction pow(final BigInteger exponent) { public BigFraction pow(final BigInteger exponent) {
if (exponent.compareTo(BigInteger.ZERO) < 0) { if (exponent.compareTo(BigInteger.ZERO) < 0) {
final BigInteger eNeg = exponent.negate(); final BigInteger eNeg = exponent.negate();
return new BigFraction(MathUtils.pow(denominator, eNeg), return new BigFraction(ArithmeticUtils.pow(denominator, eNeg),
MathUtils.pow(numerator, eNeg)); ArithmeticUtils.pow(numerator, eNeg));
} }
return new BigFraction(MathUtils.pow(numerator, exponent), return new BigFraction(ArithmeticUtils.pow(numerator, exponent),
MathUtils.pow(denominator, exponent)); ArithmeticUtils.pow(denominator, exponent));
} }
/** /**

View File

@ -16,6 +16,7 @@
*/ */
package org.apache.commons.math.util; package org.apache.commons.math.util;
import java.math.BigInteger;
import org.apache.commons.math.exception.MathArithmeticException; import org.apache.commons.math.exception.MathArithmeticException;
import org.apache.commons.math.exception.MathIllegalNumberException; import org.apache.commons.math.exception.MathIllegalNumberException;
import org.apache.commons.math.exception.NotPositiveException; import org.apache.commons.math.exception.NotPositiveException;
@ -706,6 +707,179 @@ public final class ArithmeticUtils {
return ret; return ret;
} }
/**
* Raise an int to an int power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static int pow(final int k, int e) {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
int result = 1;
int k2p = k;
while (e != 0) {
if ((e & 0x1) != 0) {
result *= k2p;
}
k2p *= k2p;
e = e >> 1;
}
return result;
}
/**
* Raise an int to a long power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static int pow(final int k, long e) {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
int result = 1;
int k2p = k;
while (e != 0) {
if ((e & 0x1) != 0) {
result *= k2p;
}
k2p *= k2p;
e = e >> 1;
}
return result;
}
/**
* Raise a long to an int power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static long pow(final long k, int e) {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
long result = 1l;
long k2p = k;
while (e != 0) {
if ((e & 0x1) != 0) {
result *= k2p;
}
k2p *= k2p;
e = e >> 1;
}
return result;
}
/**
* Raise a long to a long power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static long pow(final long k, long e) {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
long result = 1l;
long k2p = k;
while (e != 0) {
if ((e & 0x1) != 0) {
result *= k2p;
}
k2p *= k2p;
e = e >> 1;
}
return result;
}
/**
* Raise a BigInteger to an int power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static BigInteger pow(final BigInteger k, int e) {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
return k.pow(e);
}
/**
* Raise a BigInteger to a long power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static BigInteger pow(final BigInteger k, long e) {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
BigInteger result = BigInteger.ONE;
BigInteger k2p = k;
while (e != 0) {
if ((e & 0x1) != 0) {
result = result.multiply(k2p);
}
k2p = k2p.multiply(k2p);
e = e >> 1;
}
return result;
}
/**
* Raise a BigInteger to a BigInteger power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static BigInteger pow(final BigInteger k, BigInteger e) {
if (e.compareTo(BigInteger.ZERO) < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
BigInteger result = BigInteger.ONE;
BigInteger k2p = k;
while (!BigInteger.ZERO.equals(e)) {
if (e.testBit(0)) {
result = result.multiply(k2p);
}
k2p = k2p.multiply(k2p);
e = e.shiftRight(1);
}
return result;
}
/** /**
* Add two long integers, checking for overflow. * Add two long integers, checking for overflow.
* *

View File

@ -17,12 +17,10 @@
package org.apache.commons.math.util; package org.apache.commons.math.util;
import java.math.BigInteger;
import java.util.Arrays; import java.util.Arrays;
import org.apache.commons.math.exception.MathArithmeticException; import org.apache.commons.math.exception.MathArithmeticException;
import org.apache.commons.math.exception.NotFiniteNumberException; import org.apache.commons.math.exception.NotFiniteNumberException;
import org.apache.commons.math.exception.NotPositiveException;
import org.apache.commons.math.exception.NullArgumentException; import org.apache.commons.math.exception.NullArgumentException;
import org.apache.commons.math.exception.util.Localizable; import org.apache.commons.math.exception.util.Localizable;
import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.util.LocalizedFormats;
@ -276,179 +274,6 @@ public final class MathUtils {
return (x == ZS) ? ZS : (x > ZS) ? PS : NS; return (x == ZS) ? ZS : (x > ZS) ? PS : NS;
} }
/**
* Raise an int to an int power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static int pow(final int k, int e) {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
int result = 1;
int k2p = k;
while (e != 0) {
if ((e & 0x1) != 0) {
result *= k2p;
}
k2p *= k2p;
e = e >> 1;
}
return result;
}
/**
* Raise an int to a long power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static int pow(final int k, long e) {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
int result = 1;
int k2p = k;
while (e != 0) {
if ((e & 0x1) != 0) {
result *= k2p;
}
k2p *= k2p;
e = e >> 1;
}
return result;
}
/**
* Raise a long to an int power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static long pow(final long k, int e) {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
long result = 1l;
long k2p = k;
while (e != 0) {
if ((e & 0x1) != 0) {
result *= k2p;
}
k2p *= k2p;
e = e >> 1;
}
return result;
}
/**
* Raise a long to a long power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static long pow(final long k, long e) {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
long result = 1l;
long k2p = k;
while (e != 0) {
if ((e & 0x1) != 0) {
result *= k2p;
}
k2p *= k2p;
e = e >> 1;
}
return result;
}
/**
* Raise a BigInteger to an int power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static BigInteger pow(final BigInteger k, int e) {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
return k.pow(e);
}
/**
* Raise a BigInteger to a long power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static BigInteger pow(final BigInteger k, long e) {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
BigInteger result = BigInteger.ONE;
BigInteger k2p = k;
while (e != 0) {
if ((e & 0x1) != 0) {
result = result.multiply(k2p);
}
k2p = k2p.multiply(k2p);
e = e >> 1;
}
return result;
}
/**
* Raise a BigInteger to a BigInteger power.
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @throws NotPositiveException if {@code e < 0}.
*/
public static BigInteger pow(final BigInteger k, BigInteger e) {
if (e.compareTo(BigInteger.ZERO) < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
BigInteger result = BigInteger.ONE;
BigInteger k2p = k;
while (!BigInteger.ZERO.equals(e)) {
if (e.testBit(0)) {
result = result.multiply(k2p);
}
k2p = k2p.multiply(k2p);
e = e.shiftRight(1);
}
return result;
}
/** /**
* Check that the argument is a real number. * Check that the argument is a real number.
* *

View File

@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.math.BigInteger;
import org.apache.commons.math.exception.MathArithmeticException; import org.apache.commons.math.exception.MathArithmeticException;
import org.apache.commons.math.exception.MathIllegalArgumentException; import org.apache.commons.math.exception.MathIllegalArgumentException;
@ -600,6 +601,83 @@ public class ArithmeticUtilsTest {
testSubAndCheckLongFailure(min, 1L); testSubAndCheckLongFailure(min, 1L);
} }
@Test
public void testPow() {
Assert.assertEquals(1801088541, ArithmeticUtils.pow(21, 7));
Assert.assertEquals(1, ArithmeticUtils.pow(21, 0));
try {
ArithmeticUtils.pow(21, -7);
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
Assert.assertEquals(1801088541, ArithmeticUtils.pow(21, 7l));
Assert.assertEquals(1, ArithmeticUtils.pow(21, 0l));
try {
ArithmeticUtils.pow(21, -7l);
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
Assert.assertEquals(1801088541l, ArithmeticUtils.pow(21l, 7));
Assert.assertEquals(1l, ArithmeticUtils.pow(21l, 0));
try {
ArithmeticUtils.pow(21l, -7);
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
Assert.assertEquals(1801088541l, ArithmeticUtils.pow(21l, 7l));
Assert.assertEquals(1l, ArithmeticUtils.pow(21l, 0l));
try {
ArithmeticUtils.pow(21l, -7l);
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
BigInteger twentyOne = BigInteger.valueOf(21l);
Assert.assertEquals(BigInteger.valueOf(1801088541l), ArithmeticUtils.pow(twentyOne, 7));
Assert.assertEquals(BigInteger.ONE, ArithmeticUtils.pow(twentyOne, 0));
try {
ArithmeticUtils.pow(twentyOne, -7);
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
Assert.assertEquals(BigInteger.valueOf(1801088541l), ArithmeticUtils.pow(twentyOne, 7l));
Assert.assertEquals(BigInteger.ONE, ArithmeticUtils.pow(twentyOne, 0l));
try {
ArithmeticUtils.pow(twentyOne, -7l);
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
Assert.assertEquals(BigInteger.valueOf(1801088541l), ArithmeticUtils.pow(twentyOne, BigInteger.valueOf(7l)));
Assert.assertEquals(BigInteger.ONE, ArithmeticUtils.pow(twentyOne, BigInteger.ZERO));
try {
ArithmeticUtils.pow(twentyOne, BigInteger.valueOf(-7l));
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
BigInteger bigOne =
new BigInteger("1543786922199448028351389769265814882661837148" +
"4763915343722775611762713982220306372888519211" +
"560905579993523402015636025177602059044911261");
Assert.assertEquals(bigOne, ArithmeticUtils.pow(twentyOne, 103));
Assert.assertEquals(bigOne, ArithmeticUtils.pow(twentyOne, 103l));
Assert.assertEquals(bigOne, ArithmeticUtils.pow(twentyOne, BigInteger.valueOf(103l)));
}
/** /**
* Exact (caching) recursive implementation to test against * Exact (caching) recursive implementation to test against
*/ */

View File

@ -13,9 +13,6 @@
*/ */
package org.apache.commons.math.util; package org.apache.commons.math.util;
import java.math.BigInteger;
import org.apache.commons.math.exception.MathIllegalArgumentException; import org.apache.commons.math.exception.MathIllegalArgumentException;
import org.apache.commons.math.exception.MathArithmeticException; import org.apache.commons.math.exception.MathArithmeticException;
import org.apache.commons.math.exception.NotFiniteNumberException; import org.apache.commons.math.exception.NotFiniteNumberException;
@ -256,83 +253,6 @@ public final class MathUtilsTest {
Assert.assertEquals((short) (-1), MathUtils.sign((short) (-2))); Assert.assertEquals((short) (-1), MathUtils.sign((short) (-2)));
} }
@Test
public void testPow() {
Assert.assertEquals(1801088541, MathUtils.pow(21, 7));
Assert.assertEquals(1, MathUtils.pow(21, 0));
try {
MathUtils.pow(21, -7);
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
Assert.assertEquals(1801088541, MathUtils.pow(21, 7l));
Assert.assertEquals(1, MathUtils.pow(21, 0l));
try {
MathUtils.pow(21, -7l);
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
Assert.assertEquals(1801088541l, MathUtils.pow(21l, 7));
Assert.assertEquals(1l, MathUtils.pow(21l, 0));
try {
MathUtils.pow(21l, -7);
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
Assert.assertEquals(1801088541l, MathUtils.pow(21l, 7l));
Assert.assertEquals(1l, MathUtils.pow(21l, 0l));
try {
MathUtils.pow(21l, -7l);
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
BigInteger twentyOne = BigInteger.valueOf(21l);
Assert.assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, 7));
Assert.assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, 0));
try {
MathUtils.pow(twentyOne, -7);
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
Assert.assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, 7l));
Assert.assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, 0l));
try {
MathUtils.pow(twentyOne, -7l);
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
Assert.assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, BigInteger.valueOf(7l)));
Assert.assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, BigInteger.ZERO));
try {
MathUtils.pow(twentyOne, BigInteger.valueOf(-7l));
Assert.fail("Expecting MathIllegalArgumentException");
} catch (MathIllegalArgumentException e) {
// expected behavior
}
BigInteger bigOne =
new BigInteger("1543786922199448028351389769265814882661837148" +
"4763915343722775611762713982220306372888519211" +
"560905579993523402015636025177602059044911261");
Assert.assertEquals(bigOne, MathUtils.pow(twentyOne, 103));
Assert.assertEquals(bigOne, MathUtils.pow(twentyOne, 103l));
Assert.assertEquals(bigOne, MathUtils.pow(twentyOne, BigInteger.valueOf(103l)));
}
@Test @Test
public void testCheckFinite() { public void testCheckFinite() {
try { try {