You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by he...@apache.org on 2012/04/19 13:44:39 UTC

svn commit: r1327903 - in /commons/proper/jexl/trunk/src: main/java/org/apache/commons/jexl3/JexlArithmetic.java test/java/org/apache/commons/jexl3/IssuesTest.java

Author: henrib
Date: Thu Apr 19 11:44:38 2012
New Revision: 1327903

URL: http://svn.apache.org/viewvc?rev=1327903&view=rev
Log:
Updated Arithmetic to treat BigDecimal before floating points (as indicated in doc)

Modified:
    commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
    commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest.java

Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java?rev=1327903&r1=1327902&r2=1327903&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java Thu Apr 19 11:44:38 2012
@@ -25,12 +25,11 @@ import java.math.MathContext;
 /**
  * Perform arithmetic.
  * <p>
- * All arithmetic operators (+, - , *, /, %) follow the same rules regarding their arguments.
+ * The 5 arithmetic operators (+, - , *, /, %) follow the same evaluation rules regarding their arguments.
  * <ol>
  * <li>If both are null, result is 0</li>
- * <li>If either is a BigDecimal, coerce both to BigDecimal and and perform operation</li>
+ * <li>If either is a BigDecimal, coerce both to BigDecimal and  perform operation</li>
  * <li>If either is a floating point number, coerce both to Double and perform operation</li>
- * <li>If both are BigInteger, treat as BigInteger and perform operation</li>
  * <li>Else treat as BigInteger, perform operation and attempt to narrow result:
  * <ol>
  * <li>if both arguments can be narrowed to Integer, narrow result to Integer</li>
@@ -40,7 +39,7 @@ import java.math.MathContext;
  * </li>
  * </ol>
  * </p>
- * Note that the only exception throw by JexlArithmetic is ArithmeticException.
+ * Note that the only exception thrown by JexlArithmetic is ArithmeticException.
  * @since 2.0
  */
 public class JexlArithmetic {
@@ -169,16 +168,6 @@ public class JexlArithmetic {
     }
 
     /**
-     * Test if either left or right are either a Float or Double.
-     * @param left one object to test
-     * @param right the other
-     * @return the result of the test.
-     */
-    protected boolean isFloatingPointType(Object left, Object right) {
-        return left instanceof Float || left instanceof Double || right instanceof Float || right instanceof Double;
-    }
-
-    /**
      * Test if the passed value is a floating point number, i.e. a float, double
      * or string with ( "." | "E" | "e").
      *
@@ -452,40 +441,37 @@ public class JexlArithmetic {
      * @param right second value
      * @return left + right.
      */
-    public Object add(Object left, Object right) {
-        if (left == null && right == null) {
-            return controlNullNullOperands();
-        }
-
-        try {
-            // if either are floating point (double or float) use double
-            if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
-                double l = toDouble(left);
-                double r = toDouble(right);
-                return new Double(l + r);
-            }
-
-            // if either are bigdecimal use that type
-            if (left instanceof BigDecimal || right instanceof BigDecimal) {
-                BigDecimal l = toBigDecimal(left);
-                BigDecimal r = toBigDecimal(right);
-                BigDecimal result = l.add(r, getMathContext());
-                return narrowBigDecimal(left, right, result);
+        public Object add(Object left, Object right) {
+            if (left == null && right == null) {
+                return controlNullNullOperands();
             }
-
-            // otherwise treat as integers
-            BigInteger l = toBigInteger(left);
-            BigInteger r = toBigInteger(right);
-            BigInteger result = l.add(r);
-            return narrowBigInteger(left, right, result);
-        } catch (java.lang.NumberFormatException nfe) {
-            // Well, use strings!
-            if (left == null || right == null) {
-                controlNullOperand();
+            try {
+                // if either are bigdecimal use that type
+                if (left instanceof BigDecimal || right instanceof BigDecimal) {
+                    BigDecimal l = toBigDecimal(left);
+                    BigDecimal r = toBigDecimal(right);
+                    BigDecimal result = l.add(r, getMathContext());
+                    return narrowBigDecimal(left, right, result);
+                }
+                // if either are floating point (double or float) use double
+                if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
+                    double l = toDouble(left);
+                    double r = toDouble(right);
+                    return new Double(l + r);
+                }
+                // otherwise treat as integers
+                BigInteger l = toBigInteger(left);
+                BigInteger r = toBigInteger(right);
+                BigInteger result = l.add(r);
+                return narrowBigInteger(left, right, result);
+            } catch (java.lang.NumberFormatException nfe) {
+                // Well, use strings!
+                if (left == null || right == null) {
+                    controlNullOperand();
+                }
+                return toString(left).concat(toString(right));
             }
-            return toString(left).concat(toString(right));
         }
-    }
 
     /**
      * Divide the left value by the right.
@@ -498,17 +484,6 @@ public class JexlArithmetic {
         if (left == null && right == null) {
             return controlNullNullOperands();
         }
-
-        // if either are floating point (double or float) use double
-        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
-            double l = toDouble(left);
-            double r = toDouble(right);
-            if (r == 0.0) {
-                throw new ArithmeticException("/");
-            }
-            return new Double(l / r);
-        }
-
         // if either are bigdecimal use that type
         if (left instanceof BigDecimal || right instanceof BigDecimal) {
             BigDecimal l = toBigDecimal(left);
@@ -519,7 +494,15 @@ public class JexlArithmetic {
             BigDecimal result = l.divide(r, getMathContext());
             return narrowBigDecimal(left, right, result);
         }
-
+        // if either are floating point (double or float) use double
+        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
+            double l = toDouble(left);
+            double r = toDouble(right);
+            if (r == 0.0) {
+                throw new ArithmeticException("/");
+            }
+            return new Double(l / r);
+        }
         // otherwise treat as integers
         BigInteger l = toBigInteger(left);
         BigInteger r = toBigInteger(right);
@@ -541,17 +524,6 @@ public class JexlArithmetic {
         if (left == null && right == null) {
             return controlNullNullOperands();
         }
-
-        // if either are floating point (double or float) use double
-        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
-            double l = toDouble(left);
-            double r = toDouble(right);
-            if (r == 0.0) {
-                throw new ArithmeticException("%");
-            }
-            return new Double(l % r);
-        }
-
         // if either are bigdecimal use that type
         if (left instanceof BigDecimal || right instanceof BigDecimal) {
             BigDecimal l = toBigDecimal(left);
@@ -562,7 +534,15 @@ public class JexlArithmetic {
             BigDecimal remainder = l.remainder(r, getMathContext());
             return narrowBigDecimal(left, right, remainder);
         }
-
+        // if either are floating point (double or float) use double
+        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
+            double l = toDouble(left);
+            double r = toDouble(right);
+            if (r == 0.0) {
+                throw new ArithmeticException("%");
+            }
+            return new Double(l % r);
+        }
         // otherwise treat as integers
         BigInteger l = toBigInteger(left);
         BigInteger r = toBigInteger(right);
@@ -583,14 +563,6 @@ public class JexlArithmetic {
         if (left == null && right == null) {
             return controlNullNullOperands();
         }
-
-        // if either are floating point (double or float) use double
-        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
-            double l = toDouble(left);
-            double r = toDouble(right);
-            return new Double(l * r);
-        }
-
         // if either are bigdecimal use that type
         if (left instanceof BigDecimal || right instanceof BigDecimal) {
             BigDecimal l = toBigDecimal(left);
@@ -598,7 +570,12 @@ public class JexlArithmetic {
             BigDecimal result = l.multiply(r, getMathContext());
             return narrowBigDecimal(left, right, result);
         }
-
+        // if either are floating point (double or float) use double
+        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
+            double l = toDouble(left);
+            double r = toDouble(right);
+            return new Double(l * r);
+        }
         // otherwise treat as integers
         BigInteger l = toBigInteger(left);
         BigInteger r = toBigInteger(right);
@@ -616,14 +593,6 @@ public class JexlArithmetic {
         if (left == null && right == null) {
             return controlNullNullOperands();
         }
-
-        // if either are floating point (double or float) use double
-        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
-            double l = toDouble(left);
-            double r = toDouble(right);
-            return new Double(l - r);
-        }
-
         // if either are bigdecimal use that type
         if (left instanceof BigDecimal || right instanceof BigDecimal) {
             BigDecimal l = toBigDecimal(left);
@@ -631,7 +600,12 @@ public class JexlArithmetic {
             BigDecimal result = l.subtract(r, getMathContext());
             return narrowBigDecimal(left, right, result);
         }
-
+        // if either are floating point (double or float) use double
+        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
+            double l = toDouble(left);
+            double r = toDouble(right);
+            return new Double(l - r);
+        }
         // otherwise treat as integers
         BigInteger l = toBigInteger(left);
         BigInteger r = toBigInteger(right);

Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest.java?rev=1327903&r1=1327902&r2=1327903&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest.java Thu Apr 19 11:44:38 2012
@@ -785,4 +785,18 @@ public class IssuesTest extends JexlTest
         Object myObjectWithTernaryConditional = myJexlEngine.createScript(myName + "?:null").execute(myMapContext);
         assertEquals(myValue, myObjectWithTernaryConditional);
     }
+
+    public void test131() throws Exception {
+        BigDecimal sevendot475 = new BigDecimal("7.475");
+        BigDecimal SO = new BigDecimal("325");
+        JexlContext jc = new MapContext();
+        jc.set("SO", SO);
+
+        JexlEngine jexl = new Engine();
+        String expr = "2.3*SO/100";
+
+        Object evaluate = jexl.createExpression(expr).evaluate(jc);
+        assertEquals(sevendot475, (BigDecimal) evaluate);
+    }
+
 }