Project: Tomcat
Bug 50500 EL evaluation of floating-point String value vs BigInteger loses precision
Reported: 2010-12-19 19:00:53 | Status: resolved fixed

According to the EL spec ch.1.7.1, the A+B,A-B,A*B expressions when A is a "String containing ., e, or E" and B is a BigInteger have to be evaluated as follows: "coerce both A and B to BigDecimal and apply operator" The actual implementation though, instead of coercing A as String -> BigDecimal, does two coercions: String -> Double -> BigDecimal, which produces a different result. To reproduce, run the following JSP page: <% pageContext.setAttribute("a", "1.1"); pageContext.setAttribute("b", new java.math.BigInteger("1000000000000000000000")); // "c" is used to explicitly coerce arguments to BigDecimal pageContext.setAttribute("c", new java.math.BigDecimal("0")); %>${a + b}<br> ${(a+c) + (b+c)}<br> ${a - b}<br> ${(a+c) - (b+c)}<br> ${a * b}<br> ${(a+c) * (b+c)} Actual result: 1000000000000000000001.100000000000000088817841970012523233890533447265625 1000000000000000000001.1 -999999999999999999998.899999999999999911182158029987476766109466552734375 -999999999999999999998.9 1100000000000000088817.841970012523233890533447265625000000000000000000000 1100000000000000000000.0 Expected result: 1000000000000000000001.1 1000000000000000000001.1 -999999999999999999998.9 -999999999999999999998.9 1100000000000000000000.0 1100000000000000000000.0 I think it is a minor issue, though. This is reproducible in the current tc6.0.x as well. Maybe o.a.el.lang.ELArithmetic#add(Object, Object) should delegate to BIGDECIMAL instead of DOUBLE with these types of arguments.

Files changed in fix:
java/org/apache/el/lang/ELArithmetic.java test/org/apache/el/lang/TestELArithmetic.java