BigDecimal值比较(1.0).equals.(1.00)=false,以及一些其他注意事项!

505 阅读2分钟

前言

在开发中遇到过一些关于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使用常遇到的问题,和一些注意事项的总结。希望能对大家有所帮助!