简体   繁体   English

测试JSP EL表达式中BigDecimal值是否为零

[英]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. 如果someBigDecimal的值为0,但其标度不是0,则==操作返回false。 That is, it returns true when someBigDecimal is new BigDecimal("0"), but false when someBigDecimal is new BigDecimal("0.00"). 也就是说,当someBigDecimal是new BigDecimal(“0”)时返回true,但是当someBigDecimal是new BigDecimal(“0.00”)时返回false。

This results from the JSP 2.0, 2.1, and 2.2 specifications, which state: 这是由JSP 2.0,2.1和2.2规范产生的,它们声明:

For <, >, <=, >=: 对于<,>,<=,> =:

If A or B is BigDecimal, coerce both A and B to BigDecimal and use the return value of A.compareTo(B). 如果A或B是BigDecimal,则将A和B强制转换为BigDecimal并使用A.compareTo(B)的返回值。

For ==, !=: 对于==,!=:

If A or B is BigDecimal, coerce both A and B to BigDecimal and then: 如果A或B是BigDecimal,则将A和B强制转换为BigDecimal,然后:

  • If operator is ==, return A.equals(B) 如果运算符是==,则返回A.equals(B)
  • If operator is !=, return !A.equals(B) 如果操作符是!=,则返回!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. 这意味着==!=运算符会导致调用.equals()方法,该方法不仅会比较值,还会比较BigDecimals的比例。 The other comparison operators result in a call to the .compareTo() method, which compares only the values. 其他比较运算符导致调用.compareTo()方法,该方法仅比较值。

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? 但这是相当丑陋的,有没有更好的方法来做到这一点?

In JSP 2.2 EL and above this expression will evaluate to true : 在JSP 2.2 EL及更高版本中,此表达式将评估为true

${someBigDecimal.unscaledValue() == 0}

This will avoid any loss of precision but assumes that someBigDecimal is always of type BigDecimal . 这将避免任何精度损失,但假设someBigDecimal始终为BigDecimal类型。

A custom EL function is probably the best approach for older versions of EL: 自定义EL函数可能是旧版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: 该问题的核心是此Java代码的计算结果为false因为ZERO标度0 ,而新的BigDecimal具有非零标度:

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

使用最新版本的EL(例如Tomcat 7支持),您可以尝试:

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

您可以尝试signum功能:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM