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?
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.
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)).
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With