创建一个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);