Author: tn
Date: Fri Oct 18 21:40:42 2013
New Revision: 1533643

URL: http://svn.apache.org/r1533643
Log:
[MATH-1035] Simplified and improved performance of 
ArithmeticUtils.addAndCheck(long, long), thanks to derphead

Modified:
    commons/proper/math/trunk/src/changes/changes.xml
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/ArithmeticUtils.java
    
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/ArithmeticUtilsTest.java

Modified: commons/proper/math/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/changes/changes.xml?rev=1533643&r1=1533642&r2=1533643&view=diff
==============================================================================
--- commons/proper/math/trunk/src/changes/changes.xml (original)
+++ commons/proper/math/trunk/src/changes/changes.xml Fri Oct 18 21:40:42 2013
@@ -51,6 +51,9 @@ If the output is not quite correct, chec
   </properties>
   <body>
     <release version="x.y" date="TBD" description="TBD">
+      <action dev="tn" type="fix" issue="MATH-1035" due-to="derphead">
+        Simplified and improved performance of 
"ArithmeticUtils#addAndCheck(long, long)".
+      </action>
       <action dev="tn" type="add" issue="MATH-1004" due-to="Ajo Fod">
         Added new methods to compute the inverse of a matrix to 
"DiagonalMatrix"
         and "MatrixUtils".

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=1533643&r1=1533642&r2=1533643&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
 Fri Oct 18 21:40:42 2013
@@ -62,12 +62,11 @@ public final class ArithmeticUtils {
      * @param a an addend
      * @param b an addend
      * @return the sum {@code a+b}
-     * @throws MathArithmeticException if the result can not be represented as 
an
-     *         long
+     * @throws MathArithmeticException if the result can not be represented as 
an long
      * @since 1.2
      */
     public static long addAndCheck(long a, long b) throws 
MathArithmeticException {
-        return ArithmeticUtils.addAndCheck(a, b, 
LocalizedFormats.OVERFLOW_IN_ADDITION);
+        return addAndCheck(a, b, LocalizedFormats.OVERFLOW_IN_ADDITION);
     }
 
     /**
@@ -247,9 +246,7 @@ public final class ArithmeticUtils {
      * a non-negative {@code int} value.
      * @since 1.1
      */
-    public static int gcd(int p,
-                          int q)
-        throws MathArithmeticException {
+    public static int gcd(int p, int q) throws MathArithmeticException {
         int a = p;
         int b = q;
         if (a == 0 ||
@@ -326,8 +323,7 @@ public final class ArithmeticUtils {
      * @param b Positive number.
      * @return the greatest common divisor.
      */
-    private static int gcdPositive(int a,
-                                   int b) {
+    private static int gcdPositive(int a, int b) {
         if (a == 0) {
             return b;
         }
@@ -842,38 +838,11 @@ public final class ArithmeticUtils {
      * @since 1.2
      */
      private static long addAndCheck(long a, long b, Localizable pattern) 
throws MathArithmeticException {
-        long ret;
-        if (a > b) {
-            // use symmetry to reduce boundary cases
-            ret = addAndCheck(b, a, pattern);
-        } else {
-            // assert a <= b
-
-            if (a < 0) {
-                if (b < 0) {
-                    // check for negative overflow
-                    if (Long.MIN_VALUE - b <= a) {
-                        ret = a + b;
-                    } else {
-                        throw new MathArithmeticException(pattern, a, b);
-                    }
-                } else {
-                    // opposite sign addition is always safe
-                    ret = a + b;
-                }
-            } else {
-                // assert a >= 0
-                // assert b >= 0
-
-                // check for positive overflow
-                if (a <= Long.MAX_VALUE - b) {
-                    ret = a + b;
-                } else {
-                    throw new MathArithmeticException(pattern, a, b);
-                }
-            }
-        }
-        return ret;
+         final long result = a + b;
+         if (!((a ^ b) < 0 | (a ^ result) >= 0)) {
+             throw new MathArithmeticException(pattern, a, b);
+         }
+         return result;
     }
 
     /**

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=1533643&r1=1533642&r2=1533643&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
 Fri Oct 18 21:40:42 2013
@@ -62,10 +62,13 @@ public class ArithmeticUtilsTest {
         Assert.assertEquals(1, ArithmeticUtils.addAndCheck(2L, -1L));
         Assert.assertEquals(-3, ArithmeticUtils.addAndCheck(-2L, -1L));
         Assert.assertEquals(min, ArithmeticUtils.addAndCheck(min + 1, -1L));
+        Assert.assertEquals(-1, ArithmeticUtils.addAndCheck(min, max));
         testAddAndCheckLongFailure(max, 1L);
         testAddAndCheckLongFailure(min, -1L);
         testAddAndCheckLongFailure(1L, max);
         testAddAndCheckLongFailure(-1L, min);
+        testAddAndCheckLongFailure(max, max);
+        testAddAndCheckLongFailure(min, min);
     }
 
     @Test


Reply via email to