float和double类型主要是为了科学计算和工程计算而设计的。它们执行二进制浮点运算,这是为了在普遍的数值范围上提供较为精确的快速近似计算而精心设计的。它们并无提供彻底精确的结果。 java
float和double尤为不适合用于货币计算,由于要让一个float获取double精确的表示0.1是不可能的 设计
System.out.println(1.03-0.42); //结果0.6100000000000001
double funds=1.00; int itemsBought=0; for(double price=0.1;funds>=price;price+=0.1){ funds-=price; itemsBought++; } System.out.println("itemsBought="+itemsBought+";change="+funds); //结果itemsBought=3;change=0.3999999999999999解决这个问题的办法是使用BigDecimal、int或者long进行货币计算
final BigDecimal TEN_CENTS=new BigDecimal("0.1"); int itemsBought=0; BigDecimal funds=new BigDecimal("1.0"); for(BigDecimal price=TEN_CENTS;funds.compareTo(price)>=0;price=price.add(TEN_CENTS)){ itemsBought++; funds=funds.subtract(price); } System.out.println("itemsBought="+itemsBought+";change="+funds); //结果itemsBought=4;change=0.0可是使用BigDecimal有两个缺点:很不方便并且速度慢
固然也能够使用int或long,最明显的作法就是以分为单位进行计算而不是元 code
//effective java总结 ci