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
|
||||
{ "overflow: gcd({0}, {1}) is 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
|
||||
{ "evaluation failed for argument = {0}",
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.commons.math.util;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.math.MathRuntimeException;
|
||||
|
@ -1246,4 +1247,204 @@ public final class MathUtils {
|
|||
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>
|
||||
<body>
|
||||
<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">
|
||||
Fixed a comparison error when two different fractions evaluate to the
|
||||
same double due to limited precision.
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package org.apache.commons.math.util;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
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