1. “危险”的 Double
先从简单的反直觉的四则运算看起。对几个简单的浮点数进行加减乘除运算
System.out.println(0.1+0.2);
System.out.println(1.0-0.8);
System.out.println(4.015*100);
System.out.println(123.3/100);
double amount1 = 2.15;
double amount2 = 1.10;
if (amount1 - amount2 == 1.05)
System.out.println("OK");
结果如下:
0.30000000000000004
0.19999999999999996
401.49999999999994
1.2329999999999999
可以看到,输出结果和我们预期的很不一样。比如,0.1+0.2 输出的不是 0.3 而是 0.30000000000000004。出现这种问题的主要原因是,计算机是以二进制存储数值的,浮点数也不例外。Java 采用了IEEE 754 标准实现浮点数的表达和运算,你可以通过这里查看数值转化为二进制的结果。比如,0.1 的二进制表示为 0.0 0011 0011 … (0011 无限循环),再转换为十进制就是0.1000000000000000055511151231257827021181583404541015625。对于计算机而言,0.1 无法精确表达,这是浮点数计算造成精度损失的根源。
优化方案:
BigDecimal 类型,浮点数精确表达和运算的场景,一定要使用这个类型。不过&