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

发布于 2024-12-25 18:23:05 字数 943 浏览 4 评论 0原文

以下情况并不总是如您所期望的那样:

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

如果 someBigDecimal 的值为 0,但其小数位数不是 0,则 == 运算将返回 false。也就是说,当 someBigDecimal 是 new BigDecimal("0") 时返回 true,而当 someBigDecimal 是 new 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)

这意味着 ==!= 运算符会调用 .equals() 方法,该方法不仅比较值,还比较大十进制。其他比较运算符会调用 .compareTo() 方法,该方法仅比较值。

当然,以下方法可行:

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

但这相当难看,有更好的方法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

情未る 2025-01-01 18:23:05

在 JSP 2.2 EL 及更高版本中,此表达式的计算结果将为 true

${someBigDecimal.unscaledValue() == 0}

这将避免任何精度损失,但假定 someBigDecimal 始终为 BigDecimal 类型。

自定义 EL 函数 可能是旧版本 EL 的最佳方法:

${fn:isZero(someBigDecimal)}

< em>问题的核心是该 Java 代码的计算结果为 false 因为 ZERO 有一个 规模 0新的 BigDecimal 具有非零标度:

BigDecimal.ZERO.setScale(3).equals(BigDecimal.ZERO)

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)
攒眉千度 2025-01-01 18:23:05
<c:if test="${someBigDecimal.compareTo(BigDecimal.ZERO) == 0}">
<c:if test="${someBigDecimal.compareTo(BigDecimal.ZERO) == 0}">
波浪屿的海角声 2025-01-01 18:23:05

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

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

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

<c:if test="${someBigDecimal.doubleValue() == 0}">
颜漓半夏 2025-01-01 18:23:05
<c:if test="${someBigDecimal eq 0}">
<c:if test="${someBigDecimal eq 0}">
乖乖 2025-01-01 18:23:05

您可以尝试signum函数:

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

You can try signum function:

<c:if test="#{someBigDecimal.signum() == 0}">
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文