Java 中如何比较两个BigDecimal 以及BigDecimal的坑
一、背景
我们经常要比较两个数字是否相等,两个数字可以是整数、小数,我们也知道浮点数如float、double在java里是不准确的,那就会使用到BigDecimal来比较,那有些坑就必须先理清楚。
结论:
- 构造BigDecimal用 new BigDecimal(String) 或 BigDecimal.valueOf
- 比较两个BigDecimal用
b1.compareTo(b2) == 0
- 如果其中一个或两个都是字符串,则转为BigDecimal后进行比较
二、详细实验
1. 如何构造 BigDecimal
构造器有很多,用用 new BigDecimal(String) 或 BigDecimal.valueOf 来得到BigDecimal!!!,不能用其他如int/long/double的构造器。否则可能会出现坑,见”坑1″
// 正例
BigDecimal b1 = new BigDecimal("0.1");
// 反例
BigDecimal b2 = new BigDecimal(0.1);
// 正例
double d = 0.1;// 比如接口传入或库中查出的值是非字符串,如何构造?
BigDecimal b1 = BigDecimal.valueOf(d);
// 【补充】:BigDecimal.valueOf 的底层用的就是字符串的构造器
public static BigDecimal valueOf(double val) {
// Reminder: a zero double returns '0.0', so we cannot fastpath
// to use the constant ZERO. This might be important enough to
// justify a factory approach, a cache, or a few private
// constants, later.
return new BigDecimal(Double.toString(val));
}
2. 如何比较两个BigDecimal 的值(不要用equals比较!!!)
使用 compareTo()
方法,不要用equals!!!
BigDecimal b1 = new BigDecimal("1.0");
BigDecimal b2 = new BigDecimal("1.00");
// 正例
System.out.println(b1.compareTo(b2) == 0);// 等于0表示两者相等,会忽略精度
// 反例
System.out.println(b1.equals(b2));// 返回false因为两者精度不一样即使实际值一样但最终返回false
3. 如何比较String类型之间的数字的值是否相等
转为BigDecimal进行比较!不要用字符串比较!!!
-
其中一个是字串,另一个是BigDecimal
String value1 = "0.1"; BigDecimal b = new BigDecimal("0.10"); // 将String转为BigDecimal再用compareTo比较 BigDecimal v = new BigDeimal(value1);// 要确保value1能够转为数字,如果value1是abc这样的字串会出现NumberFormatExcception System.out.println(b.compareTo(v));
-
两个都是字串:都转为compareTo进行比较
4. 什么是 BigDecimal 的精度(Scale)
精度就是小数点后的位数(官方文档解释得很复杂…)
System.out.println(new BigDecimal("1").scale());// 0
System.out.println(new BigDecimal("1.0").scale());// 1
System.out.println(new BigDecimal("1.00").scale());// 2
System.out.println(new BigDecimal("1.010").scale());// 3
System.out.println(new BigDecimal("0").scale());// 0
System.out.println(new BigDecimal("-0").scale());// 0
System.out.println(new BigDecimal("-1").scale());// 0
System.out.println(new BigDecimal("-1.00").scale());// 2
System.out.println(new BigDecimal("-1.1").scale());// 1
附录:补充 BigDecimal 的坑
坑1:构造器的坑
BigDecimal b1 = new BigDecimal("0.1");
BigDecimal b2 = new BigDecimal(0.1);
System.out.println(b1);// 打印:0.1
System.out.println(b2);// 打印:0.1000000000000000055511151231257827021181583404541015625
System.out.println(b1.compareTo(b2));// -1,说明b1小于b2
坑2:比较要用compareTo不要用equals
BigDecimal b1 = new BigDecimal("1.0");
BigDecimal b2 = new BigDecimal("1.00");
System.out.println(b1 == b2);// false,因为是不同的对象
System.out.println(b1.equals(b2));// false,因为scale不一样
System.out.println(b1.compareTo(b2));// 0,0就是两者相等。compareTo会忽略精度
其他
这些问题请自行再研究
- 关于BigDecimal 的格式化问题(百分比、保留小数位数、货币…)
- 关于BigDecimal的加减乘除运算问题、除0的问题
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/135075.html