Java 解惑 -02:找零时刻
🏷️ 《Java 解惑》
java
System.out.println(2.00 - 1.10); // print 0.8999999999999999
这个问题和 这篇博客 中描述的 0.30000000000000004 问题都来自于同样的原因:二进制无法准确地表示大部分小数。
java
System.out.println(0.1 + 0.2); // 0.30000000000000004
虽然可以通过如下格式化的方式,调整打印的结果以显示正确的值,但其储存的值仍然是错误的。
java
System.out.printf("%.2f%n", 2.00 - 1.10); // print 0.90
解决这种金额相关的计算,最好的办法是降低计算的单位,采用整形来计算。比如人民币可以采用分,甚至是厘来计算,将浮点运算转换为整形计算。
java
System.out.println((200 - 110) + "cents"); // print 90cents
如果必须使用小数,则应该使用 BigDecimal
类型。不过在 Java 中没有对 BigDecimal
型做运算符的重载,导致使用起来不是很方便。
另外一个必须要注意的是使用 String
型来实例化 BigDecimal
,否则由于入参的不精确进而导致 BigDecimal
的实例也不精确。
java
System.out.println(new BigDecimal(2.00).subtract(new BigDecimal(1.10))); // print 0.899999999999999911182158029987476766109466552734375
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.10"))); // print 0.90