由于计算机在运算浮点数时,会丢失精度,实际项目中用BigDecimal代替浮点运算。并且由于数据库底层存储浮点数时,如mysql的float及double符合IEEE标准但会受计算机硬件及操作系统影响,而丢失部分精度。mysql的decimal字段,倒是能够解决,它最大表示65位数字,其中小数位最多30。个人觉得最好关于钱这块的字段,数据库存储还是string好,这样可以防止不同数据库的差异。缺点是查询这个字段时,需要转回数值给前台(具体业务需要,只是展示的话不需要);
如:
double d=29.0*0.01;
System.out.println("d:"+d);
System.out.println(d*100);
System.out.println((int)(d*100));
会输出28,原因是d与100运算结果为:28.999999999999996,而最后转int进行了舍入。
用BigDecimal实现上述运算如下:
BigDecimal a=new BigDecimal("29");
BigDecimal b=new BigDecimal("0.01");
BigDecimal c=a.multiply(b);
BigDecimal res=c.multiply(new BigDecimal(100));
System.out.println("res:"+res);
结果是29
所以实际项目中,会使用BigDecimal来做浮点运算。
最好用BigDecimal,用其中string作为参数的构造函数。如下:
BigDecimal有两个方法用于比较一个是equals一个是compare。
前者会比较小数点位数与值,因此10.00与10.000是不同的数。
而用后者compare比较时,由于该方法只要是值相等就认为相等,因此会返回true。
BigDecimal a=new BigDecimal("10.00");
BigDecimal b=new BigDecimal("10.000");
System.out.println("a==b?"+a.compareTo(b));