Java 中如何比较两个BigDecimal 以及BigDecimal的坑

有目标就不怕路远。年轻人.无论你现在身在何方.重要的是你将要向何处去。只有明确的目标才能助你成功。没有目标的航船.任何方向的风对他来说都是逆风。因此,再遥远的旅程,只要有目标.就不怕路远。没有目标,哪来的劲头?一车尔尼雷夫斯基

导读:本篇文章讲解 Java 中如何比较两个BigDecimal 以及BigDecimal的坑,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

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

(1)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!