前言
在开发中遇到过一些关于BigDecimal使用的问题。 例如:BigDecimal 类型比较数值是否相等,不能使用equals方法,‘0.0’比较‘0.00’会返回false。 以及数值精度、除法的舍入模式、常量等问题。 这篇文章说明一下这些问题,应在实际使用中规避这些错误。
1. BigDecimal 类型比较大小
- 为什么使用
BigDecimal.equals()比较数值大小时,明明值是相等的却是返回false?- 原因:
equals方法不仅比较数值,还比较精度(即小数点后的有效位数)。例如,new BigDecimal("10.0")和new BigDecimal("10.00")用equals方法比较会返回false。
- 原因:
- 不能直接使用
BigDecimal.equals()方法对比数值相等时,要怎么样对比BigDecimal类型的数值是否相等?- 可以使用
BigDecimal类的compareTo方法来比较两个BigDecimal对象的大小。compareTo:只比较数值,不比较精度。compareTo方法返回以下值:- 负数:如果当前
BigDecimal小于比较的BigDecimal。 - 零:如果两个
BigDimal相等。 - 正数:如果当前
BigDecimal大于比较的BigDecimal。
- 负数:如果当前
- 可以使用
- 比较前需要注意判断两个
BigDecimal是否为null
2. BigDecimal 的精度问题
BigDecimal 是精确的,但需要注意构造方式:
- 使用字符串构造器:
BigDecimal构造函数接受String类型参数时不会有精度问题,而接受double类型时可能会引入不可预期的精度问题。
- 推荐使用
BigDecimal.valueOf(),等同于new BigDecimal(string),在BigDecimal源码中调用了new BigDecimal()方法,不需要手动创建对象,也能规避小数值时的精度损失。
3. 避免除零问题
在涉及除法运算时,如果分母为 BigDecimal,要确保分母非零,否则会抛出 ArithmeticException。
4. 使用正确的舍入模式
BigDecimal.divide() 需要指定精度和舍入模式,否则可能抛出 ArithmeticException。
5. 避免误用常量
BigDecimal value = new BigDecimal("0"); // 不推荐
BigDecimal value = BigDecimal.valueOf(0); // 不推荐
BigDecimal value = BigDecimal.ZERO; // 推荐
结语
这些是我平时在Java开发中使用
BigDecimal使用常遇到的问题,和一些注意事项的总结。希望能对大家有所帮助!