Java 为什么0.1在float中表示正确?(我知道为什么不是2.0-1.9的结果)

Java 为什么0.1在float中表示正确?(我知道为什么不是2.0-1.9的结果),java,floating-point,Java,Floating Point,最近我读了很多关于浮点表示的书(包括这篇:)。 现在我明白了0.1无法正确表示,当我这样做时: System.out.println(2.0f - 1.9f); 我永远也得不到确切的结果 因此,问题是: 如何在以下代码中表示0.1f以正确打印0.1? 那是某种合成糖吗? 在我上面提到的文章中说:0.1在内存中表示为0.1000000149011919384765625。那么,为什么我没有得到这段代码的输出: System.out.println(0.1f); Java如何处理这个问题?Sys

最近我读了很多关于浮点表示的书(包括这篇:)。 现在我明白了0.1无法正确表示,当我这样做时:

System.out.println(2.0f - 1.9f);
我永远也得不到确切的结果

因此,问题是: 如何在以下代码中表示0.1f以正确打印0.1? 那是某种合成糖吗? 在我上面提到的文章中说:0.1在内存中表示为0.1000000149011919384765625。那么,为什么我没有得到这段代码的输出:

System.out.println(0.1f);

Java如何处理这个问题?

System.out.println对浮点和双精度进行舍入。它使用
Float.toString()
,它本身(在oraclew JDK中)将委托给
FloatingDecimal
类-您可以查看详细信息

如果您尝试:

BigDecimal bd = new BigDecimal(0.1f);
System.out.println(bd);

您将在
Float.toString(Float)
的文档中看到0.1f:0.10000001490119384765625的实际值。

(它将始终给出与正在打印的字符串相同的结果):

m或a的小数部分必须打印多少位?必须至少有一个数字来表示小数部分,除此之外,还必须有足够多的数字来唯一区分参数值和float类型的相邻值


由于0.1f是最接近精确值
0.1
的可表示浮点数,因此不需要更多的数字来唯一地将其与
float
类型的任何其他值区分开来是有意义的。

第二个输出有多少个有效数字?哇,多快啊!非常感谢!你根本不需要看源代码-你只需要看
Float.toString(Float)
的文档,它给出了一个非常清楚的原因,为什么
Float.toString(0.1f)
将返回“0.1”。@JonSkeet我的意思是他可以看看源代码,看看它是如何完成的,不是为什么-您在回答中提到了为什么。但是表达式在传递到
System.println
之前会进行计算。如果有不同的结果,这只能是因为表达式解析为不同的值。那么,为什么表达式
2.0f-1.9f
的结果与表达式
0.1f
有所不同呢?@Michael,因为
2.0f-1.9f!=0.1f
。在这里查看它们的精确值:应该注意的是,实现并不是在所有情况下都正确地实现javadoc;请参阅和(关于printf,所以不是相同的javadoc…)。然而,这不是问题所在。