场景:
在开发中,经常会遇到数值计算类的业务,就会用到 BigDecimal 类型,但是需要注意涉及小数的数值可能会出现精度丢失问题,导致计算结果不精准
一、BigDecimal 精度丢失案例
1、new BigDecimal 转换方式
BigDecimal test1 = new BigDecimal(1);
BigDecimal test2 = new BigDecimal("1");
BigDecimal test3 = new BigDecimal(0.15);
BigDecimal test4 = new BigDecimal("0.15");
System.out.println("test1 = " + test1);
System.out.println("test2 = " + test2);
System.out.println("test3 = " + test3);
System.out.println("test4 = " + test4);输出:
test1 = 1
test2 = 1
test3 = 0.1499999999999999944488848768742172978818416595458984375
test4 = 0.15小结:
上述结果可以看出,使用 new BigDecimal 转换方式,在参数为非字符串小数的时候,会出现精度丢失问题
2、BigDecimal.valueOf 转换方式
BigDecimal test1 = BigDecimal.valueOf(1);
BigDecimal test2 = BigDecimal.valueOf(Double.parseDouble("1"));
BigDecimal test3 = BigDecimal.valueOf(0.15);
BigDecimal test4 = BigDecimal.valueOf(Double.parseDouble("0.15"));
System.out.println("test1 = " + test1);
System.out.println("test2 = " + test2);
System.out.println("test3 = " + test3);
System.out.println("test4 = " + test4);输出:
test1 = 1
test2 = 1.0
test3 = 0.15
test4 = 0.15小结:
1、上述结果可以看出,使用 BigDecimal.valueOf 转换方式,在参数为字符串整数的时候,需要先转成 Double 类型,再转成 BigDecimal 类型
2、本来是整数,转成 Double 类型的时候默认保留一位小数,导致转成 BigDecimal 类型也保留了一位小数
二、格式化、千位分隔
1、格式化保留小数位数,默认四舍五入
String decimalFormat = NumberUtil.decimalFormat("0.00", 10.567);
System.out.println("decimalFormat = " + decimalFormat);输出:
decimalFormat = 10.572、格式化保留小数位数,指定舍或入
String decimalFormat = NumberUtil.decimalFormat("0.00", 10.567, RoundingMode.DOWN);
System.out.println("decimalFormat = " + decimalFormat);输出:
decimalFormat = 10.563、千位分隔
String decimalFormat = NumberUtil.decimalFormat("#,##0.00", 10800000.567, RoundingMode.DOWN);
System.out.println("decimalFormat = " + decimalFormat);输出:
decimalFormat = 10,800,000.56注意:
格式化的值类型不能是字符串,否则会报错(Cannot format given Object as a Number)
总结:
1、推荐使用 BigDecimal.valueOf 方式,此方式不会出现小数精度丢失问题
2、如果需要转换的是字符串类型,推荐 new BigDecimal 方式
3、更推荐使用 HuTool 包下的 NumberUtil.toBigDecimal 转换方式,此方式也不会出现小数精度丢失问题。如果是字符串,NumberUtil.toBigDecimal 也是通过 new BigDecimal 转换的
4、BigDecimal 转换保留千位分隔符格式模板为:#,##0.00
版权声明:本文为hkl_Forever原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。