最近在项目中的财务管理模块遇到一个问题就是数据库字段建的类型是float,在计算后会引起精度缺失问题
抛开数据库建立的不当以外,遇到这个问题的解决方法如下:
例子:
public static void main(String[] args) {
// TODO Auto-generated method stub
Float f1 = 24f;
Float f2 = 40.3f;
Double d1 = 24d;
Double d2 = 40.3;
System.out.println(f1*f2);
System.out.println(d1*d2);
}
输出结果为
967.19995
967.1999999999999
解决方法:
BigDecimal
我们将float或者double类型的先转换成bigdecimal类型再进行计算,就非常精确,所以这就是为什么金额(金钱)相关的数据存储类型都用decimal或者bigdecimal。
看了一下bigdecimal的构造方法很多
这块建议使用BigDecimal(String val)来解决
原因在此引用一位前辈的一段话
有人可能认为在 Java 中写入 new BigDecimal(0.1) 所创建的 BigDecimal 正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入 到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。
所以,使用double和float作为数据源的话,使用public BigDecimal(double val)产生的结果带有一定的不可预知性。
最后贴上一些bigdecimal的简单使用方法
public static void main(String[] args) {
// TODO Auto-generated method stub
//bigdecimal比较大小
BigDecimal big1 = new BigDecimal("21.6");
BigDecimal big2 = new BigDecimal("10.8");
System.out.println(big1.compareTo(big2));
//-1表示小于,0是等于,1是大于
if(big2.compareTo(big1)>0){
//如果big2>big1
System.out.println("--------"+big2);
}else{
//否则
System.out.println("--------"+big1);
}
//bigdecimal计算
//加
System.out.println(big1.add(big2));
//减
System.out.println(big1.subtract(big2));
//乘
System.out.println(big1.multiply(big2));
//除
System.out.println(big1.divide(big2));
}
输出结果:
1
--------21.6
32.4
10.8
233.28
2