John S
John S

Reputation: 21482

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?

Upvotes: 19

Views: 23547

Answers (5)

Saljack
Saljack

Reputation: 2344

You can try signum function:

<c:if test="#{someBigDecimal.signum() == 0}">

Upvotes: 2

peakmuma
peakmuma

Reputation: 1624

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

Upvotes: 2

McDowell
McDowell

Reputation: 108859

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)

Upvotes: 13

Assen Kolov
Assen Kolov

Reputation: 4393

<c:if test="${someBigDecimal.compareTo(BigDecimal.ZERO) == 0}">

Upvotes: 4

Bozho
Bozho

Reputation: 597016

With the latest version of EL (supported by Tomcat 7 for example), you can try:

<c:if test="${someBigDecimal.doubleValue() == 0}">

Upvotes: 2

Related Questions