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);
+ }
+
}