Added some utility functions to compute powers with integral types (int, long, BigInteger)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@760014 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e143317c7d
commit
40223343f0
|
@ -47,6 +47,8 @@ public class MessagesResources_fr
|
||||||
// org.apache.commons.math.util.MathUtils
|
// org.apache.commons.math.util.MathUtils
|
||||||
{ "overflow: gcd({0}, {1}) is 2^31",
|
{ "overflow: gcd({0}, {1}) is 2^31",
|
||||||
"d\u00e9passement de capacit\u00e9 : le PGCD de {0} et {1} vaut 2^31" },
|
"d\u00e9passement de capacit\u00e9 : le PGCD de {0} et {1} vaut 2^31" },
|
||||||
|
{ "cannot raise an integral value to a negative power ({0}^{1})",
|
||||||
|
"impossible d''\u00e9lever une valeur enti\u00e8re \u00e0 une puissance n\u00e9gative ({0}^{1})" },
|
||||||
|
|
||||||
// org.apache.commons.math.FunctionEvaluationException
|
// org.apache.commons.math.FunctionEvaluationException
|
||||||
{ "evaluation failed for argument = {0}",
|
{ "evaluation failed for argument = {0}",
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package org.apache.commons.math.util;
|
package org.apache.commons.math.util;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.apache.commons.math.MathRuntimeException;
|
import org.apache.commons.math.MathRuntimeException;
|
||||||
|
@ -1246,4 +1247,204 @@ public final class MathUtils {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raise an int to an int power.
|
||||||
|
* @param k number to raise
|
||||||
|
* @param e exponent (must be positive or null)
|
||||||
|
* @return k<sup>e</sup>
|
||||||
|
* @exception IllegalArgumentException if e is negative
|
||||||
|
*/
|
||||||
|
public static int pow(final int k, int e)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
|
if (e < 0) {
|
||||||
|
throw MathRuntimeException.createIllegalArgumentException(
|
||||||
|
"cannot raise an integral value to a negative power ({0}^{1})",
|
||||||
|
k, 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 null)
|
||||||
|
* @return k<sup>e</sup>
|
||||||
|
* @exception IllegalArgumentException if e is negative
|
||||||
|
*/
|
||||||
|
public static int pow(final int k, long e)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
|
if (e < 0) {
|
||||||
|
throw MathRuntimeException.createIllegalArgumentException(
|
||||||
|
"cannot raise an integral value to a negative power ({0}^{1})",
|
||||||
|
k, 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 null)
|
||||||
|
* @return k<sup>e</sup>
|
||||||
|
* @exception IllegalArgumentException if e is negative
|
||||||
|
*/
|
||||||
|
public static long pow(final long k, int e)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
|
if (e < 0) {
|
||||||
|
throw MathRuntimeException.createIllegalArgumentException(
|
||||||
|
"cannot raise an integral value to a negative power ({0}^{1})",
|
||||||
|
k, 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 null)
|
||||||
|
* @return k<sup>e</sup>
|
||||||
|
* @exception IllegalArgumentException if e is negative
|
||||||
|
*/
|
||||||
|
public static long pow(final long k, long e)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
|
if (e < 0) {
|
||||||
|
throw MathRuntimeException.createIllegalArgumentException(
|
||||||
|
"cannot raise an integral value to a negative power ({0}^{1})",
|
||||||
|
k, 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 null)
|
||||||
|
* @return k<sup>e</sup>
|
||||||
|
* @exception IllegalArgumentException if e is negative
|
||||||
|
*/
|
||||||
|
public static BigInteger pow(final BigInteger k, int e)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
|
if (e < 0) {
|
||||||
|
throw MathRuntimeException.createIllegalArgumentException(
|
||||||
|
"cannot raise an integral value to a negative power ({0}^{1})",
|
||||||
|
k, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return k.pow(e);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raise a BigInteger to a long power.
|
||||||
|
* @param k number to raise
|
||||||
|
* @param e exponent (must be positive or null)
|
||||||
|
* @return k<sup>e</sup>
|
||||||
|
* @exception IllegalArgumentException if e is negative
|
||||||
|
*/
|
||||||
|
public static BigInteger pow(final BigInteger k, long e)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
|
if (e < 0) {
|
||||||
|
throw MathRuntimeException.createIllegalArgumentException(
|
||||||
|
"cannot raise an integral value to a negative power ({0}^{1})",
|
||||||
|
k, 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 null)
|
||||||
|
* @return k<sup>e</sup>
|
||||||
|
* @exception IllegalArgumentException if e is negative
|
||||||
|
*/
|
||||||
|
public static BigInteger pow(final BigInteger k, BigInteger e)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
|
if (e.compareTo(BigInteger.ZERO) < 0) {
|
||||||
|
throw MathRuntimeException.createIllegalArgumentException(
|
||||||
|
"cannot raise an integral value to a negative power ({0}^{1})",
|
||||||
|
k, 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,9 @@ The <action> type attribute can be add,update,fix,remove.
|
||||||
</properties>
|
</properties>
|
||||||
<body>
|
<body>
|
||||||
<release version="2.0" date="TBD" description="TBD">
|
<release version="2.0" date="TBD" description="TBD">
|
||||||
|
<action dev="luc" type="add">
|
||||||
|
Added some utility functions to compute powers with integral types (int, long, BigInteger).
|
||||||
|
</action>
|
||||||
<action dev="luc" type="fix" issue="MATH-252">
|
<action dev="luc" type="fix" issue="MATH-252">
|
||||||
Fixed a comparison error when two different fractions evaluate to the
|
Fixed a comparison error when two different fractions evaluate to the
|
||||||
same double due to limited precision.
|
same double due to limited precision.
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
package org.apache.commons.math.util;
|
package org.apache.commons.math.util;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -1077,4 +1078,80 @@ public final class MathUtilsTest extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPow() {
|
||||||
|
|
||||||
|
assertEquals(1801088541, MathUtils.pow(21, 7));
|
||||||
|
assertEquals(1, MathUtils.pow(21, 0));
|
||||||
|
try {
|
||||||
|
MathUtils.pow(21, -7);
|
||||||
|
fail("Expecting IllegalArgumentException");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected behavior
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(1801088541, MathUtils.pow(21, 7l));
|
||||||
|
assertEquals(1, MathUtils.pow(21, 0l));
|
||||||
|
try {
|
||||||
|
MathUtils.pow(21, -7l);
|
||||||
|
fail("Expecting IllegalArgumentException");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected behavior
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(1801088541l, MathUtils.pow(21l, 7));
|
||||||
|
assertEquals(1l, MathUtils.pow(21l, 0));
|
||||||
|
try {
|
||||||
|
MathUtils.pow(21l, -7);
|
||||||
|
fail("Expecting IllegalArgumentException");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected behavior
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(1801088541l, MathUtils.pow(21l, 7l));
|
||||||
|
assertEquals(1l, MathUtils.pow(21l, 0l));
|
||||||
|
try {
|
||||||
|
MathUtils.pow(21l, -7l);
|
||||||
|
fail("Expecting IllegalArgumentException");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected behavior
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger twentyOne = BigInteger.valueOf(21l);
|
||||||
|
assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, 7));
|
||||||
|
assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, 0));
|
||||||
|
try {
|
||||||
|
MathUtils.pow(twentyOne, -7);
|
||||||
|
fail("Expecting IllegalArgumentException");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected behavior
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, 7l));
|
||||||
|
assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, 0l));
|
||||||
|
try {
|
||||||
|
MathUtils.pow(twentyOne, -7l);
|
||||||
|
fail("Expecting IllegalArgumentException");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected behavior
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(BigInteger.valueOf(1801088541l), MathUtils.pow(twentyOne, BigInteger.valueOf(7l)));
|
||||||
|
assertEquals(BigInteger.ONE, MathUtils.pow(twentyOne, BigInteger.ZERO));
|
||||||
|
try {
|
||||||
|
MathUtils.pow(twentyOne, BigInteger.valueOf(-7l));
|
||||||
|
fail("Expecting IllegalArgumentException");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected behavior
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger bigOne =
|
||||||
|
new BigInteger("1543786922199448028351389769265814882661837148" +
|
||||||
|
"4763915343722775611762713982220306372888519211" +
|
||||||
|
"560905579993523402015636025177602059044911261");
|
||||||
|
assertEquals(bigOne, MathUtils.pow(twentyOne, 103));
|
||||||
|
assertEquals(bigOne, MathUtils.pow(twentyOne, 103l));
|
||||||
|
assertEquals(bigOne, MathUtils.pow(twentyOne, BigInteger.valueOf(103l)));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue