验证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
相关产品推荐
相关产品推荐

