运行以下行后:
double d=Float.parseFloat("9.99");
System.out.println(""+d);
我得到了这个:9.989999771118164
我希望看到:9.99
为什么以及如何解决这个问题?
=============================================== ======
编辑:我应该使用的是:double d = Double.parseDouble(“9.99”)打印出9.99。这是我的错,但看到详细的答案很有意思,谢谢!
答案 0 :(得分:14)
如果您想要精确的十进制值,请使用BigDecimal
。否则,了解二进制浮点的工作原理,并准备好应对后果。 (当然,即使BigDecimal
也无法代表"第三个"确实如此。)
请注意,调用Float.parseFloat
很奇怪,但将结果分配给double
... 分配更常见导致float
或使用Double.parseDouble
开始。但是,在任何一种情况下,结果不正好是9.99。数字9.99不能精确地以二进制浮点表示,而不是三乘除的结果可以用十进制表示精确写出。
我没有特别关于Java二进制浮点的任何文章,但是它与C#二进制浮点之间不应该有任何明显的差异,我做有an article about。
您应该使用哪种类型取决于您所代表的语义。我使用人工制造的经验法则" artificial"货币等价值最好以十进制格式表示(例如BigDecimal
)而#34;自然"高度和宽度等值更适合float
/ double
。
答案 1 :(得分:4)
数字9.99
不能完全表示为浮点数,因此Float.parseFloat
返回了最接近的可表示浮点数。
有关详细信息,请在Google上搜索“what every computer scientist should know about floating-point arithmetic”。
答案 2 :(得分:2)
这与Java无关。它与浮点表示有关。如果你想将数字表示为两位小数浮点数,我建议你使用printf或String.format:
System.out.println(String.format("%.2f", 9.99));
此致
答案 3 :(得分:1)
浮点数仍由位表示,其具有有限数量的可能配置,因此即使浮点数也是离散的(它们不能表示具有任意精度的值并且发生舍入)。你在这里观察到的是浮点不准确,9.99无法用数据类型精确表示。你如何“修复”这取决于你想要做什么。
答案 4 :(得分:0)
如果您尝试使用Double.parseDouble()
,那么您将得到预期的结果。