优秀的编程知识分享平台

网站首页 > 技术文章 正文

BigDecimal常见的几个误区(bigdecimal用equals)

nanyue 2024-08-25 10:23:01 技术文章 5 ℃

创建一个BigDecimal

  • 精度丢失问题

在创建浮点数的BigDecimal对象时,不直接使用数字,而是采用字符串,不会产生精度问题。因为直接使用2.4这样的浮点数,计算机表示浮点数时就会有精度丢失问题。

// 错误的创建,得出的结果为: 2.3999999...
BigDecimal bigDecimal = new BigDecimal(2.4);

// 正确的创建
BigDecimal bigDecimal2 = new BigDecimal("2.4");
  • 系统内置大量的已有的对象,和Integer的缓存池一样

同时也是运用了享元模式,这样编程的好处在于不用重复创建对象,减少系统的的内存开销和创建对象的时间开销。

// 0
  public static final BigDecimal ZERO =
        zeroThroughTen[0];
// 1
    public static final BigDecimal ONE =
        zeroThroughTen[1];
// 10
 public static final BigDecimal TEN =
        zeroThroughTen[10];

等等

进行四则运算

  • 以加法为例,BigDecimal对象可以和另外一个BigDecimal求和,并不会改变当前BigDecimal对象的值,需要使用返回值。

很多时候写代码写的太快会忘掉,可以用工具类会好一些。

BigDecimal bigDecimal = new BigDecimal("1");
BigDecimal bigDecimal1 = new BigDecimal("2");
// 此时bigDecimal的值并没有变化
// bigDecimal.add(bigDecimal1);

bigDecimal = bigDecimal.add(bigDecimal1);
  • 除法运算中精度设置问题,导致线上偶发报错,无限不循环报错
BigDecimal bigDecimal = new BigDecimal("13");
BigDecimal bigDecimal1 = new BigDecimal("3");

// 报错Non-terminating decimal expansion; no exact representable decimal result.
bigDecimal.divide(bigDecimal1).setScale(3, RoundingMode.HALF_UP);

// 正确写法
bigDecimal.divide(bigDecimal1, 3, RoundingMode.HALF_UP);

BigDecimal比较

  • 两个Integer对象,比较是否相等,可以使用equals,但是在BigDecimal中确有坑
BigDecimal bigDecimal1 = new BigDecimal("1.20");
BigDecimal bigDecimal2 = new BigDecimal("1.20");
// true
System.out.println(bigDecimal1.equals(bigDecimal2));
// true
System.out.println(bigDecimal1.equals(bigDecimal2));

BigDecimal bigDecimal3 = new BigDecimal("1.200");
BigDecimal bigDecimal4 = new BigDecimal("1.20");
// false
System.out.println(bigDecimal3.equals(bigDecimal4));
// true
System.out.println(bigDecimal3.compareTo(bigDecimal4) == 0);
  • 由于精度不同,equlas导致返回不同, 所以BigDecimal比较,只采用compareTo,不采用equals。

与stream结合使用求和

  • 采用stream的reduce,从0开始累加
// 为了自测使用,快速构造的一个BigDecimal List
List<BigDecimal> bigDecimals = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).stream().map(x -> new BigDecimal(Objects.toString(x))).collect(Collectors.toList());

BigDecimal reduce = bigDecimals.stream().reduce(BigDecimal.ZERO, BigDecimal::add);

// 55
System.out.println(reduce);



最近发表
标签列表