首先我们来做一个实验:
public static void main(String[] args) {
System.out.println(2.00-1.90);
}
我猜大多数人第一反应都是应该打印出来0.1或者0.10。最开始的时候我也是这样想的,可是实际一测试竟然发现结果为:0.10000000000000009
这是为什么呢?
我们来研究一下:
如果我们单看Double中的toString方法的话,就会知道程序打印出来的小数,是足以将double类型的值与最靠近它的临近值区分出来的最短的小数,也就是说打印出来0.1才是对的。但是实际情况其实并不是这样。
这个问题的关键在于1.90其实并不能精确的表示成为一个double类型,因此它被表示成为最接近它的double类型。
改程序从2中减去的就是这个值,所以其实计算的结果其实并不是最接近0.1这个正确结果的double值。而是我们看到的那个。
这问题的根本其实就是告诉我并不是所有的小树都可以用二级制浮点数来精确表示的。
我们的一般解决方案有如下几种:
第一种,自欺欺人的方法:
System.out.printf("%.3f%n",2.00-1.90);
这样的结果肯定是三位小数的。
第二种,使用执行精确小数运算的BigDecimal
当然,这里我们需要使用BigDecimal(String)的这个构造器而不是BigDecimal(Double)的这个,原因是如果使用double类型的这个,那么创建的将仍然不是正确的。
比如new BigDecimal(0.9)返回的将是:0.90000000000000002220446049250313080847263336181640625
例:
public static void main(String[] args) {
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.90")));
}
这时候显示的结果就是0.1了。
参考:java解惑.pdf
推荐:java解惑.pdf