为啥有些浮点数出现尾随 0

Posted

技术标签:

【中文标题】为啥有些浮点数出现尾随 0【英文标题】:Why do some floating point numbers appear with a trailing 0为什么有些浮点数出现尾随 0 【发布时间】:2011-11-25 17:51:25 【问题描述】:

有谁知道为什么数字 0.001 到 0.009 被渲染为带有尾随 0 的字符串,而其他数字却没有。例如数字 0.01 到 0.09 没有。

System.out.println(Locale.getDefault());
for (int i = 0; i <= 20; i++)
    System.out.println(i / 1e3);

打印

en_GB
0.0
0.0010
0.0020
0.0030
0.0040
0.0050
0.0060
0.0070
0.0080
0.0090
0.01
0.011
0.012
0.013
0.014
0.015
0.016
0.017
0.018
0.019
0.02

编辑 DecimalFormat 的代码似乎与语言环境无关。如果我跑

for (Locale l : Locale.getAvailableLocales())   
    Locale.setDefault(l);
    System.out.println(l + " " + 1 / 1e3);

在 Ubuntu 11.04 上的 Java 6 更新 26 我得到

ja_JP 0.0010
es_PE 0.0010
en 0.0010
... many locales with the same result ...
sv_SE 0.0010
da_DK 0.0010
es_HN 0.0010

在我得到的同一系统上的 Java 7 上

ms_MY 0.001
ar_QA 0.001
is_IS 0.001
... many locales with the same result ...
el_CY 0.001
hu 0.001
fr_FR 0.001

【问题讨论】:

嗯...我不明白这种行为。我得到“0.001”等。你在哪个地区? 我得到了这种行为,fr_CH,但我也得到了 Locale.US。 可能是JVM,我用的是Windows7 jdk 1.6.22 @Matthew:很有趣。顺便说一句,我在 Windows 7 上使用 JDK 7。 与 Ubuntu 10.10、JDK 1.6.0_20 的 @JonSkeet 相同 【参考方案1】:

这被确定为 Java 1.3 - Java 6 中的错误:http://bugs.java.com/view_bug.do?bug_id=4428022‎

编辑:至于为什么会发生这种情况,这是从 OpenJDK 6 移植的错误报告中提到的修复:http://hg.openjdk.java.net/jdk6/jdk6/jdk/rev/8159687b6316

事实证明这是一个错误。 (修复将

【讨论】:

一个似乎花了十年时间才修复的错误。 :P 追踪修复此问题的补丁(信息已添加到答案中)。【参考方案2】:

对于那些感兴趣的,here is a diff 之间的 FloatingDecimal 类负责创建双精度的字符串表示。从 diff 中可以看出,补丁修复了 dtoa() 方法中指数为 -3 时遇到的特殊情况。

【讨论】:

以上是关于为啥有些浮点数出现尾随 0的主要内容,如果未能解决你的问题,请参考以下文章

js浮点数精度丢失问题及如何解决js中浮点数计算不精准

解决JavaScript浮点数计算精度问题

php随机浮点数都有哪些?比如从0.1到3.0中随机一个浮点数出来?

C51浮点数显示浮点数表示方法

php中浮点数计算问题

为啥C++里面浮点与整数相乘的结果跟在计算器里的不一样呢?浮点我选的float