Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing if a BigDecimal value is zero in a JSP EL Expression

The following does not always behave as you would expect:

<c:if test="${someBigDecimal == 0}">

If someBigDecimal has a value of 0, but has a scale other than 0, the == operation returns false. That is, it returns true when someBigDecimal is new BigDecimal("0"), but false when someBigDecimal is new BigDecimal("0.00").

This results from the JSP 2.0, 2.1, and 2.2 specifications, which state:

For <, >, <=, >=:

If A or B is BigDecimal, coerce both A and B to BigDecimal and use the return value of A.compareTo(B).

For ==, !=:

If A or B is BigDecimal, coerce both A and B to BigDecimal and then:

  • If operator is ==, return A.equals(B)
  • If operator is !=, return !A.equals(B)

This means the == and != operators result in a call to the .equals() method, which compares not only the values, but also the scale of the BigDecimals. The other comparison operators result in a call to the .compareTo() method, which compares only the values.

Of course, the following would work:

<c:if test="${not ((someBigDecimal < 0) or (someBigDecimal > 0))}">

But this is rather ugly, is there a better way to do this?

like image 661
John S Avatar asked Jan 06 '12 22:01

John S


People also ask

How do I check if BigDecimal is zero?

Using the compareTo Method Two BigDecimal objects that are equal in value but have a different scale (like 2.0 and 2.00) are considered equal by this method. Therefore, we can check BigDecimal. ZERO. compareTo(givenBdNumber) == 0 to decide if givenBdNumber has the value zero.

What is BigDecimal in Java?

In java, BigDecimal consists of a random precision integer scale and a 32-bit integer scale. If positive or zero, the scale is the number of digits to the right of the decimal point. If less than zero, the unscaled value of the number is multiplied by ten to the power of the negation of the scale(10^(-scale)).


1 Answers

In JSP 2.2 EL and above this expression will evaluate to true:

${someBigDecimal.unscaledValue() == 0}

This will avoid any loss of precision but assumes that someBigDecimal is always of type BigDecimal.

A custom EL function is probably the best approach for older versions of EL:

${fn:isZero(someBigDecimal)}

The core of the problem is that this Java code evaluates to false because ZERO has a scale of 0 and the new BigDecimal has a non-zero scale:

BigDecimal.ZERO.setScale(3).equals(BigDecimal.ZERO)
like image 176
McDowell Avatar answered Oct 22 '22 16:10

McDowell