BigDecimal 的 equals() 和 compareTo() 的用法与区别
BigDecimal 常使用方法
在日常涉及金额和数量时离不开 BigDecimal 类型。
在 java.math.BigDecimal API中可以看到 提供了很多方法,除了加减乘除计算外,
下面说两个常用且需谨慎的两个方法:compareTo()、equals()。
比较大小 compareTo(BigDecimal val)
两个数比较大小:
1 | a.compareTo(b) < 0 // a小于b |
与 0 比较:
BigDecimal 提供与个别数字比较,
例如:BigDecimal.ZERO、BigDecimal.ONE、BigDecimal.TEN…
1 | a.compareTo(BigDecimal.ZERO) > 0 // a大于0 |
是否相等 equals(Object x)
1 | * Compares this {@code BigDecimal} with the specified |
在源码注释中能看到 equals() 方法不像 compareTo() 方法,equals() 方法考虑到value(值)和 scale(精度)两个因素。
1 | BigDecimal a = new BigDecimal(0.1); |
我们发现 BigDecimal 的 equals() 方法对0.1和0.10进行比较的时候:
当使用int、long、double 定义 BigDecimal时,结果为 true
当使用 String 定义 BigDecimal 时,结果为 false
为什么 a 和 b 相等? c 和 d 不等呢?
BigDecimal(int)、BigDecimal(long)、BigDecimal(double)、BigDecimal(String) 创建出来的 BigDecimal 的精度是不同的。
①由于 int 和 long 是整数,在下面源码注释中声明它们的精度为 0
1 | * Translates an {@code int} into a {@code BigDecimal}. The |
1 | * Translates a {@code long} into a {@code BigDecimal}. The |
②double 表示的是一个近似值
new BigDecimal(0.1) 或者 new BigDecimal(0.10) 创建的 BigDecimal,创建出来的值并不是正好等于 0.1,
值都是0.1000000000000000055511151231257827021181583404541015625。
在控制台执行发现 new BigDecimal(0.10).scale == 55
和 new BigDecimal(0.1).scale == 55
精度都是 55,其中 scale(精度)为小数的位数,所以 a 与 b 是相等的。
1 | * One might assume that writing {@code new BigDecimal(0.1)} in |
③String: BigDecimal(String val)
- new BigDecimal(“0.1”) 创建出来的值正好等于 0.1,精度为 1
- new BigDecimal(“0.10”) 创建出来的值正好等于 0.10,精度为 2
由于精度不同,所以 c 和 d 是不相等的。
1 | * "0" [0,0] |
c 和 d 如何相等?
1 | * Compares this {@code BigDecimal} with the specified |
为了使 c 和 d 相等,在 compareTo() 源码注释中可看到,不会比较 scale,而是直接比较值的大小。
1 | BigDecimal c = new BigDecimal("0.1"); |
小心使用 BigDecimal!
Title: BigDecimal 的 equals() 和 compareTo() 的用法与区别
Author: Amber
Date: 2022-04-01
Last Update: 2024-10-29
Blog Link: https://wyiyi.github.io/amber/2022/04/01/BigDecimal/
Copyright Declaration: Copyright © 2022 Amber.