You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2013/10/29 13:01:12 UTC
svn commit: r1536683 - in /commons/proper/math/trunk/src:
main/java/org/apache/commons/math3/exception/util/
main/java/org/apache/commons/math3/util/
main/resources/assets/org/apache/commons/math3/exception/util/
test/java/org/apache/commons/math3/exce...
Author: erans
Date: Tue Oct 29 12:01:12 2013
New Revision: 1536683
URL: http://svn.apache.org/r1536683
Log:
MATH-1047
Overflow checking in "ArithmeticUtils.pow(int,int)".
Added "LocalizedFormats.BASE" error pattern.
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/ArithmeticUtils.java
commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/ArithmeticUtilsTest.java
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java?rev=1536683&r1=1536682&r2=1536683&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java Tue Oct 29 12:01:12 2013
@@ -205,6 +205,7 @@ public enum LocalizedFormats implements
NOT_POSITIVE_ELEMENT_AT_INDEX("element {0} is not positive: {1}"),
NOT_POSITIVE_EXPONENT("invalid exponent {0} (must be positive)"),
NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE("number of elements should be positive ({0})"),
+ BASE("base ({0})"), /* keep */
EXPONENT("exponent ({0})"), /* keep */
NOT_POSITIVE_LENGTH("length must be positive ({0})"),
LENGTH("length ({0})"), /* keep */
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/ArithmeticUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/ArithmeticUtils.java?rev=1536683&r1=1536682&r2=1536683&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/ArithmeticUtils.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/ArithmeticUtils.java Tue Oct 29 12:01:12 2013
@@ -632,25 +632,45 @@ public final class ArithmeticUtils {
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
- * @return k<sup>e</sup>
+ * @return \( k^e \)
* @throws NotPositiveException if {@code e < 0}.
+ * @throws MathArithmeticException if the result would overflow.
*/
- public static int pow(final int k, int e) throws NotPositiveException {
+ public static int pow(final int k,
+ final int e)
+ throws NotPositiveException,
+ MathArithmeticException {
if (e < 0) {
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
- int result = 1;
- int k2p = k;
- while (e != 0) {
- if ((e & 0x1) != 0) {
- result *= k2p;
+ try {
+ int exp = e;
+ int result = 1;
+ int k2p = k;
+ while (true) {
+ if ((exp & 0x1) != 0) {
+ result = mulAndCheck(result, k2p);
+ }
+
+ exp >>= 1;
+ if (exp == 0) {
+ break;
+ }
+
+ k2p = mulAndCheck(k2p, k2p);
}
- k2p *= k2p;
- e = e >> 1;
- }
- return result;
+ return result;
+ } catch (MathArithmeticException mae) {
+ // Add context information.
+ mae.getContext().addMessage(LocalizedFormats.OVERFLOW);
+ mae.getContext().addMessage(LocalizedFormats.BASE, k);
+ mae.getContext().addMessage(LocalizedFormats.EXPONENT, e);
+
+ // Rethrow.
+ throw mae;
+ }
}
/**
Modified: commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties?rev=1536683&r1=1536682&r2=1536683&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties (original)
+++ commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties Tue Oct 29 12:01:12 2013
@@ -176,6 +176,7 @@ DEGREES_OF_FREEDOM = degr\u00e9s de libe
NOT_POSITIVE_ELEMENT_AT_INDEX = l''\u00e9l\u00e9ment {0} n''est pas positif : {1}
NOT_POSITIVE_EXPONENT = exposant {0} invalide (doit \u00eatre positif)
NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE = le nombre d''\u00e9l\u00e9ments devrait \u00eatre positif ({0})
+BASE = base ({0})
EXPONENT = exposant ({0})
NOT_POSITIVE_LENGTH = la longueur doit \u00eatre positive ({0})
LENGTH = longueur ({0})
Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java?rev=1536683&r1=1536682&r2=1536683&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java Tue Oct 29 12:01:12 2013
@@ -30,7 +30,7 @@ public class LocalizedFormatsTest {
@Test
public void testMessageNumber() {
- Assert.assertEquals(314, LocalizedFormats.values().length);
+ Assert.assertEquals(315, LocalizedFormats.values().length);
}
@Test
Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/ArithmeticUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/ArithmeticUtilsTest.java?rev=1536683&r1=1536682&r2=1536683&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/ArithmeticUtilsTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/ArithmeticUtilsTest.java Tue Oct 29 12:01:12 2013
@@ -460,6 +460,50 @@ public class ArithmeticUtilsTest {
}
+ @Test(expected=MathArithmeticException.class)
+ public void testPowIntIntOverflow() {
+ final int base = 21;
+ final int exp = 8;
+ ArithmeticUtils.pow(base, exp);
+ }
+ @Test
+ public void testPowIntIntNoOverflow() {
+ final int base = 21;
+ final int exp = 7;
+ ArithmeticUtils.pow(base, exp);
+ }
+
+ @Test(expected=MathArithmeticException.class)
+ public void testPowNegativeIntIntOverflow() {
+ final int base = -21;
+ final int exp = 8;
+ ArithmeticUtils.pow(base, exp);
+ }
+ @Test
+ public void testPowNegativeIntIntNoOverflow() {
+ final int base = -21;
+ final int exp = 7;
+ ArithmeticUtils.pow(base, exp);
+ }
+
+ @Test
+ public void testPowMinusOneInt() {
+ final int base = -1;
+ for (int i = 0; i < 100; i++) {
+ final int pow = ArithmeticUtils.pow(base, i);
+ Assert.assertEquals("i: " + i, i % 2 == 0 ? 1 : -1, pow);
+ }
+ }
+
+ @Test
+ public void testPowOneInt() {
+ final int base = 1;
+ for (int i = 0; i < 100; i++) {
+ final int pow = ArithmeticUtils.pow(base, i);
+ Assert.assertEquals("i: " + i, 1, pow);
+ }
+ }
+
@Test
public void testIsPowerOfTwo() {
final int n = 1025;