You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

验证BigDecimal stripTrailingZeros与相等性断言是否对所有值成立

关于BigDecimal断言的有效性分析

给定:

BigDecimal a = ...;
BigDecimal b = ...;

以下断言并非对所有a和b的取值都成立,存在边缘情况导致部分断言失败,具体分析如下:

断言1:if (a.compareTo(b) == 0) assert a.stripTrailingZeros().equals(b.stripTrailingZeros())

不成立,存在反例:

  • 示例:a = new BigDecimal("12300"),b = new BigDecimal("1.23E+4")
  • 两者compareTo结果为0(数值相等),但stripTrailingZeros()处理后:
    • a的结果为1.23E+4(scale=-2)
    • b的结果为12300(scale=0)
  • 由于BigDecimal.equals()同时比较数值和精度(scale),处理后的两者equals返回false,触发断言失败。

断言2:if (a.compareTo(b) != 0) assert !(a.stripTrailingZeros().equals(b.stripTrailingZeros()))

成立:

  • 若a.compareTo(b) != 0,说明两者数值本质不等。stripTrailingZeros()仅移除尾部零,不会改变数值大小,因此处理后的a和b数值仍不等,equals必然返回false,断言始终成立。

断言3:if (a.stripTrailingZeros().equals(b.stripTrailingZeros())) assert(a.compareTo(b) == 0)

成立:

  • 若stripTrailingZeros()后两者equals,说明数值和精度均完全相同,原a和b的数值必然相等,因此compareTo结果为0,断言始终成立。

断言4:if (!(a.stripTrailingZeros().equals(b.stripTrailingZeros()))) assert(a.compareTo(b) != 0)

不成立,存在反例:

  • 示例同断言1:a = new BigDecimal("12300"),b = new BigDecimal("1.23E+4")
  • 两者stripTrailingZeros()后equals返回false,但compareTo结果为0,断言要求compareTo != 0,触发断言失败。

核心原因

BigDecimal.compareTo()仅比较数值大小,而equals()同时比较数值和精度(scale)。stripTrailingZeros()对初始精度不同的相同数值,可能生成不同scale的结果,导致equals判断不等,但compareTo判断相等。

内容的提问来源于stack exchange,提问作者Klitos Kyriacou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 14:37:33