float和double类型主要是为了科学计算和工程计算而设计的。他们执行二进制浮点运算,这是为了在广泛的数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们并没有提供完全精确的结果,所以不应该被用于需要精确结果的场合。float和double类型尤其不是和用于货币计算,因为要让一个float或者double精确地标识0.1(或者10的任何其他负数次方值)是不能的。
举例说明代码如下:
public static void main(String[] args) {
//所有金额
double funds = 1;
//购买次数
int itemsBought = 0;
//初次购买是0.1,后续每次购买都会涨价0.1
for (double price = 0.1; funds >= price; price += 0.1) {
funds -= price;
itemsBought++;
}
System.out.println(String.format("一共能买%d件物品", itemsBought));
System.out.println("余额:" + funds);
}
运行结果为:
修改后代码如下:
public static void main(String[] args) {
//所有金额
BigDecimal funds = new BigDecimal(1);
//购买次数
int itemsBought = 0;
//初次购买是0.1,后续每次购买都会涨价0.1
for (BigDecimal price = new BigDecimal("0.1"); funds.compareTo(price) >= 0;price = price.add(new BigDecimal("0.1"))) {
funds =funds.subtract(price);
itemsBought++;
}
System.out.println(String.format("一共能买%d件物品", itemsBought));
System.out.println("余额:" + funds);
}
运行结果如下:
根据以上代码得知:如果需要精确计算的话需要使用BigDecimal进行计算。
如果数字位数超过18位,也必须使用BigDecimal。