场景描述
做实际项目的时候,由于使用Double类的valueOf得到一个用String类型保存的金额参数(单位为元),当需要转换成以分为单位即整形表示(Integer类表示)时,需要用之前得到的double数据乘以100,强制将它转换成int类型的数据。可是结果可能会出现一分钱的误差,这会是一个很大的bug,以下模拟了问题的现象以及提出了解决问题的办法。
1、将String类型的数据用Double.valueOf(param)转换后乘以一个整数,使得恰好它的小数点后的数字值为全为0,但是会出现精度问题
String amt = "4385.73";System.out.println("String 类型值转换为Double 类型的值后的值为:" + Double.valueOf(amt));//4385.73Double amount = Double.valueOf(amt) * 100;System.out.println("String 类型值转换为Double 类型的值后的值为========= " + (int)(Double.valueOf(amt) * 100));//438572System.out.println("String 类型值转换为Double 类型的值后的值为:" + Double.valueOf(amt) * 100); //438572.99999999994String amountStr = String.valueOf(amount.intValue());System.out.println("Double类型值转换为String 类型的值后的值为:" + amountStr);//438572
2、解决办法,使用BigDecimal类代替Double类来解决金额转换的精度问题
String amt = "4385.73";BigDecimal bd=new BigDecimal(amt);//设置小数位数,第一个变量是小数位数,第二个变量是取舍方法(四舍五入)bd=bd.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP);System.out.println("amt of BigDecimal:"+ bd); //438573//转化为字符串输出String OutString=bd.toString();System.out.println("amt of String:"+ OutString); //438573System.out.println("amt of int:" + bd.intValue());//438573