BigDecimal
BigDecimal是不可变的任意精度的有符号的十进制数,常用在金额的计算,在java 中 double 的+-*/会丢失精度比如说:
System.out.println(1.01+2.02); //3.0300000000000002
BigDecimal的常用方法:
public BigDecimal(double val)
public BigDecimal(String val)
public static BigDecimal valueOf(double val)
public BigDecimal add(BigDecimal augend)
public BigDecimal subtract(BigDecimal subtrahend)
public BigDecimal multiply(BigDecimal multiplicand)
public BigDecimal divide(BigDecimal divisor)
System.out.println(new BigDecimal(2.02));//2.020000000000000017763568394002504646778106689453125
System.out.println(new BigDecimal("2.02"));//2.02
BigDecimal(double val) 和BigDecimal(String val)的区别 使用BigDecimal(double val) 同样会丢失精度,或者使用 public static BigDecimal valueOf(double val) 它本质还是用的 BigDecimal(String val)
public static BigDecimal valueOf(double val) {
return new BigDecimal(Double.toString(val));
}
那 1.01+2.02 该如何计算
BigDecimal b1 = new BigDecimal("1.01");
BigDecimal b2 = new BigDecimal("2.02");
System.out.println(b1.add(b2).toString());//3.03
BigDecimal b1 = new BigDecimal(1.01);
BigDecimal b2 = new BigDecimal(2.02);
System.out.println(b1.add(b2).toString());//3.0300000000000000266453525910037569701671600341796875
System.out.println(b1.add(b2).doubleValue());//3.0300000000000002
同样的加减乘除使用BigDecimal(String val) 会确保精度不丢失
保留俩位小数点问题
1.是一定要保留俩位小数点还是保留的俩位小数点不超过俩位
第一种: 一定要保留俩位小数点
public static String round(String v, int scale, int round_mode) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(v);
return b.setScale(scale, round_mode).toString();
}
System.out.println(round("1.17676", 2, BigDecimal.ROUND_HALF_UP));//1.18
System.out.println(round("1.17476", 2, BigDecimal.ROUND_HALF_UP));//1.17
System.out.println(round("1.1", 2, BigDecimal.ROUND_HALF_UP));//1.10
第二种:小数点不超过俩位
public static double round(String v, int scale, int round_mode) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(v);
return b.setScale(scale, round_mode).doubleValue();
}
System.out.println(round("1.17676", 2, BigDecimal.ROUND_HALF_UP));//1.18
System.out.println(round("1.17476", 2, BigDecimal.ROUND_HALF_UP));//1.17
System.out.println(round("1.1", 2, BigDecimal.ROUND_HALF_UP));//1.1
以上也是 doubleValue() 和 toString() 导致的差别
参考其他文章:
java保留2位小数及BigDecimal使用
浅谈BigDecimal