BigDecimal如何比较大小

43 阅读1分钟

1.BigDecimal 不能通过eqals()方法比较两值大小

列如:尽管精度不一样,但是数值一样,理论上也应该视为同一数字。

BigDecimal bigDecimal = new BigDecimal("0.1");
BigDecimal bigDecima2 = new BigDecimal("0.10");
BigDecimal bigDecima3 = new BigDecimal("0.1");
System.out.println(bigDecimal.equals(bigDecima2)); //false
System.out.println(bigDecimal.equals(bigDecima3)); //true

image.png

2.正确的方法使用compareTo()进行比较两值

BigDecimal bigDecimal = new BigDecimal("0.1");
BigDecimal bigDecima2 = new BigDecimal("0.10");
BigDecimal bigDecima3 = new BigDecimal("0.1");
System.out.println(bigDecimal.compareTo(bigDecima2)); //0
System.out.println(bigDecimal.compareTo(bigDecima3)); //0

**BigDecimal提供了compareTo()方法,如果两值相等就返回0,不相等就返回-1**

3.拓展:

BigDecimal(double)和BigDecimal(String)有什么区别?

double表示的是一个近似值,当我们使用 new BigDecimal(0.1) 创建一个 BigDecimal 的时候,其实创建出来的值并不是正好等于 0.1 的。而当我们使用 new BigDecimal("0.1")创建一个 BigDecimal 的时候,其实创建出来的值正好就是等于 0.1 的。

《阿里巴巴Java开发手册》中有一条建议,或者说是要求:

12.【强制】禁止使用构造方法 BigDecimal(double) 的方式把 double 值转化为 BigDecimal 对象

说明:BigDecimal(double) 存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。

如:BigDecimal g=new BigDecimal(0.1F); 实际的存储值为:0.100000001490116119384765625

正例:优先推荐入参为 String 的构造方法,或使用 BigDecimal 的 valueOf 方法,此方法内部其实执行了 Double 的 toString,而 Double 的 toString 按 double 的实际能表达的精度对尾数进行了截断。

BigDecimal recommend1 = new BigDecimal("0.1");
BigDecimal recommend2 = new BigDecimal.valueOf(0.1);