web-dev-qa-db-ja.com

JSPEL式でBigDecimal値がゼロかどうかをテストする

以下は、必ずしも期待どおりに動作するとは限りません。

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

SomeBigDecimalの値が0で、スケールが0以外の場合、==演算はfalseを返します。つまり、someBigDecimalが新しいBigDecimal( "0")の場合はtrueを返し、someBigDecimalが新しいBigDecimal( "0.00")の場合はfalseを返します。

これは、JSP 2.0、2.1、および2.2の仕様によるものです。

<、>、<=、> =の場合:

AまたはBがBigDecimalの場合、AとBの両方をBigDecimalに強制変換し、A.compareTo(B)の戻り値を使用します。

==の場合、!=:

AまたはBがBigDecimalの場合、AとBの両方をBigDecimalに強制変換してから、次のようにします。

  • 演算子が==の場合、A.equals(B)を返します
  • 演算子が!=の場合、!A.equals(B)を返します。

つまり、_==_および_!=_演算子は、値だけでなくBigDecimalsのスケールも比較する.equals()メソッドの呼び出しになります。他の比較演算子は、値のみを比較する.compareTo()メソッドの呼び出しになります。

もちろん、以下は機能します。

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

しかし、これはかなり醜いです、これを行うためのより良い方法はありますか?

19
John S

JSP 2.2 EL以降では、この式はtrueと評価されます。

${someBigDecimal.unscaledValue() == 0}

これにより、精度の低下は回避されますが、someBigDecimalは常にタイプBigDecimalであると想定されます。

カスタムEL関数 はおそらく古いバージョンのELにとって最良のアプローチです:

${fn:isZero(someBigDecimal)}

問題の核心は、このJavaコードはfalseに評価されるため、ZEROには scale of 0および新しいBigDecimalのスケールはゼロ以外です:

BigDecimal.ZERO.setScale(3).equals(BigDecimal.ZERO)
11
McDowell
<c:if test="${someBigDecimal.compareTo(BigDecimal.ZERO) == 0}">
3
Assen Kolov

ELの最新バージョン(Tomcat 7でサポートされているなど)を使用すると、次のことができます。

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

符号関数を試すことができます:

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