java中保留俩位小数问题 以及BigDecimal的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Fengj04/article/details/81367831

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

猜你喜欢

转载自blog.csdn.net/Fengj04/article/details/81367831
今日推荐