Add BigDecimal support for SpEl numeric operations
Prior to this change, SpEL supported numeric operations for int, float,
ect. `new java.math.BigDecimal('0.1') > 0` evaluated to false
(BigDecimal is truncated to int)
This commit introduces support for BigDecimal operations for all
mathematical operators. `new java.math.BigDecimal('0.1') > 0` now
evaluates to true (the comparison is made with BigDecimals)
Issue: SPR-9164
pull/418/head
giovannidalloglio14 years agocommitted byPhillip Webb
@ -45,27 +49,26 @@ public class StandardTypeComparator implements TypeComparator {
@@ -45,27 +49,26 @@ public class StandardTypeComparator implements TypeComparator {
@ -636,6 +638,7 @@ public class EvaluationTests extends ExpressionTestCase {
@@ -636,6 +638,7 @@ public class EvaluationTests extends ExpressionTestCase {
staticclassSpr9751{
publicStringtype="hello";
publicBigDecimalbd=newBigDecimal("2");
publicdoubleddd=2.0d;
publicfloatfff=3.0f;
publiclonglll=66666L;
@ -755,6 +758,13 @@ public class EvaluationTests extends ExpressionTestCase {
@@ -755,6 +758,13 @@ public class EvaluationTests extends ExpressionTestCase {
@ -801,6 +811,14 @@ public class EvaluationTests extends ExpressionTestCase {
@@ -801,6 +811,14 @@ public class EvaluationTests extends ExpressionTestCase {
@ -907,6 +925,13 @@ public class EvaluationTests extends ExpressionTestCase {
@@ -907,6 +925,13 @@ public class EvaluationTests extends ExpressionTestCase {
@ -953,6 +978,13 @@ public class EvaluationTests extends ExpressionTestCase {
@@ -953,6 +978,13 @@ public class EvaluationTests extends ExpressionTestCase {
evaluate("3L == new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3.0d == new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3L == new java.math.BigDecimal('3.1')",false,Boolean.class);
evaluate("3.0d == new java.math.BigDecimal('3.1')",false,Boolean.class);
evaluate("3.0d == new java.math.BigDecimal('3.0')",true,Boolean.class);
evaluate("3 eq 5",false,Boolean.class);
evaluate("5 eQ 3",false,Boolean.class);
@ -104,6 +156,16 @@ public class OperatorTests extends ExpressionTestCase {
@@ -104,6 +156,16 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("3.0f eq 5.0f",false,Boolean.class);
evaluate("3.0f EQ 3.0f",true,Boolean.class);
evaluate("'abc' EQ null",false,Boolean.class);
evaluate("new java.math.BigDecimal('5') eq new java.math.BigDecimal('5')",true,Boolean.class);
evaluate("new java.math.BigDecimal('3') eq new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("new java.math.BigDecimal('5') eq new java.math.BigDecimal('3')",false,Boolean.class);
evaluate("3 eq new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3L eq new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3.0d eq new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3L eq new java.math.BigDecimal('3.1')",false,Boolean.class);
evaluate("3.0d eq new java.math.BigDecimal('3.1')",false,Boolean.class);
evaluate("3.0d eq new java.math.BigDecimal('3.0')",true,Boolean.class);
}
@Test
@ -113,12 +175,32 @@ public class OperatorTests extends ExpressionTestCase {
@@ -113,12 +175,32 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("6 != 6",false,Boolean.class);
evaluate("3.0f != 5.0f",true,Boolean.class);
evaluate("3.0f != 3.0f",false,Boolean.class);
evaluate("new java.math.BigDecimal('5') != new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("new java.math.BigDecimal('3') != new java.math.BigDecimal('5')",true,Boolean.class);
evaluate("new java.math.BigDecimal('5') != new java.math.BigDecimal('3')",true,Boolean.class);
evaluate("3 != new java.math.BigDecimal('5')",true,Boolean.class);
evaluate("3L != new java.math.BigDecimal('5')",true,Boolean.class);
evaluate("3.0d != new java.math.BigDecimal('5')",true,Boolean.class);
evaluate("3L != new java.math.BigDecimal('3.1')",true,Boolean.class);
evaluate("3.0d != new java.math.BigDecimal('3.1')",true,Boolean.class);
evaluate("3.0d != new java.math.BigDecimal('3.0')",false,Boolean.class);
evaluate("3 ne 5",true,Boolean.class);
evaluate("5 nE 3",true,Boolean.class);
evaluate("6 Ne 6",false,Boolean.class);
evaluate("3.0f NE 5.0f",true,Boolean.class);
evaluate("3.0f ne 3.0f",false,Boolean.class);
evaluate("new java.math.BigDecimal('5') ne new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("new java.math.BigDecimal('3') ne new java.math.BigDecimal('5')",true,Boolean.class);
evaluate("new java.math.BigDecimal('5') ne new java.math.BigDecimal('3')",true,Boolean.class);
evaluate("3 ne new java.math.BigDecimal('5')",true,Boolean.class);
evaluate("new java.math.BigDecimal('3') ne 5",true,Boolean.class);
evaluate("3L ne new java.math.BigDecimal('5')",true,Boolean.class);
evaluate("3.0d ne new java.math.BigDecimal('5')",true,Boolean.class);
evaluate("3L ne new java.math.BigDecimal('3.1')",true,Boolean.class);
evaluate("3.0d ne new java.math.BigDecimal('3.1')",true,Boolean.class);
evaluate("3.0d ne new java.math.BigDecimal('3.0')",false,Boolean.class);
}
@Test
@ -135,11 +217,31 @@ public class OperatorTests extends ExpressionTestCase {
@@ -135,11 +217,31 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("'abc' >= 'def'",false,Boolean.class);
evaluate("'def' >= 'abc'",true,Boolean.class);
evaluate("'abc' >= 'abc'",true,Boolean.class);
evaluate("new java.math.BigDecimal('5') >= new java.math.BigDecimal('5')",true,Boolean.class);
evaluate("new java.math.BigDecimal('3') >= new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("new java.math.BigDecimal('5') >= new java.math.BigDecimal('3')",true,Boolean.class);
evaluate("3 >= new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3L >= new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3.0d >= new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3L >= new java.math.BigDecimal('3.1')",false,Boolean.class);
evaluate("3.0d >= new java.math.BigDecimal('3.1')",false,Boolean.class);
evaluate("3.0d >= new java.math.BigDecimal('3.0')",true,Boolean.class);
evaluate("3 GE 5",false,Boolean.class);
evaluate("5 gE 3",true,Boolean.class);
evaluate("6 Ge 6",true,Boolean.class);
evaluate("3L ge 5L",false,Boolean.class);
evaluate("new java.math.BigDecimal('5') ge new java.math.BigDecimal('5')",true,Boolean.class);
evaluate("new java.math.BigDecimal('3') ge new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("new java.math.BigDecimal('5') ge new java.math.BigDecimal('3')",true,Boolean.class);
evaluate("3 ge new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("new java.math.BigDecimal('3') ge 5",false,Boolean.class);
evaluate("3L ge new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3.0d ge new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3L ge new java.math.BigDecimal('3.1')",false,Boolean.class);
evaluate("3.0d ge new java.math.BigDecimal('3.1')",false,Boolean.class);
evaluate("3.0d ge new java.math.BigDecimal('3.0')",true,Boolean.class);
}
@Test
@ -152,11 +254,29 @@ public class OperatorTests extends ExpressionTestCase {
@@ -152,11 +254,29 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("5.0d > 3.0d",true,Boolean.class);
evaluate("'abc' > 'def'",false,Boolean.class);
evaluate("'def' > 'abc'",true,Boolean.class);
evaluate("new java.math.BigDecimal('3') > new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("new java.math.BigDecimal('5') > new java.math.BigDecimal('3')",true,Boolean.class);
evaluate("3 > new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3L gt new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3.0d gt new java.math.BigDecimal('5')",false,Boolean.class);
evaluate("3L gt new java.math.BigDecimal('3.1')",false,Boolean.class);
evaluate("3.0d gt new java.math.BigDecimal('3.1')",false,Boolean.class);
evaluate("3.0d gt new java.math.BigDecimal('3.0')",false,Boolean.class);
}
@Test
@ -169,6 +289,32 @@ public class OperatorTests extends ExpressionTestCase {
@@ -169,6 +289,32 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("3.0d * 5.0d",15.0d,Double.class);
}
@Test
publicvoidtestMixedOperandsBigDecimal(){
evaluate("3 * new java.math.BigDecimal('5')",newBigDecimal("15"),BigDecimal.class);
evaluate("3L * new java.math.BigDecimal('5')",newBigDecimal("15"),BigDecimal.class);
evaluate("3.0d * new java.math.BigDecimal('5')",newBigDecimal("15.0"),BigDecimal.class);
evaluate("3 + new java.math.BigDecimal('5')",newBigDecimal("8"),BigDecimal.class);
evaluate("3L + new java.math.BigDecimal('5')",newBigDecimal("8"),BigDecimal.class);
evaluate("3.0d + new java.math.BigDecimal('5')",newBigDecimal("8.0"),BigDecimal.class);
evaluate("3 - new java.math.BigDecimal('5')",newBigDecimal("-2"),BigDecimal.class);
evaluate("3L - new java.math.BigDecimal('5')",newBigDecimal("-2"),BigDecimal.class);
evaluate("3.0d - new java.math.BigDecimal('5')",newBigDecimal("-2.0"),BigDecimal.class);
evaluate("3 / new java.math.BigDecimal('5')",newBigDecimal("1"),BigDecimal.class);
evaluate("3 / new java.math.BigDecimal('5.0')",newBigDecimal("0.6"),BigDecimal.class);
evaluate("3 / new java.math.BigDecimal('5.00')",newBigDecimal("0.60"),BigDecimal.class);
evaluate("3L / new java.math.BigDecimal('5.0')",newBigDecimal("0.6"),BigDecimal.class);
evaluate("3.0d / new java.math.BigDecimal('5.0')",newBigDecimal("0.6"),BigDecimal.class);
evaluate("5 % new java.math.BigDecimal('3')",newBigDecimal("2"),BigDecimal.class);
evaluate("3 % new java.math.BigDecimal('5')",newBigDecimal("3"),BigDecimal.class);
evaluate("3L % new java.math.BigDecimal('5')",newBigDecimal("3"),BigDecimal.class);
evaluate("3.0d % new java.math.BigDecimal('5')",newBigDecimal("3.0"),BigDecimal.class);
@ -258,6 +409,10 @@ public class OperatorTests extends ExpressionTestCase {
@@ -258,6 +409,10 @@ public class OperatorTests extends ExpressionTestCase {
@ -284,6 +439,18 @@ public class OperatorTests extends ExpressionTestCase {
@@ -284,6 +439,18 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("6.0d % 3.5d",2.5d,Double.class);
}
@Test
publicvoidtestBigDecimals(){
evaluate("3 + new java.math.BigDecimal('5')",newBigDecimal("8"),BigDecimal.class);
evaluate("3 - new java.math.BigDecimal('5')",newBigDecimal("-2"),BigDecimal.class);
evaluate("3 * new java.math.BigDecimal('5')",newBigDecimal("15"),BigDecimal.class);
evaluate("3 / new java.math.BigDecimal('5')",newBigDecimal("1"),BigDecimal.class);
evaluate("5 % new java.math.BigDecimal('3')",newBigDecimal("2"),BigDecimal.class);