为什么 DecimalFormat ".#" 和 "0.#" 在 23.0 上有不同的结果?
Why does DecimalFormat ".#" and "0.#" have different results on 23.0?
为什么 java.text.DecimalFormat
评估以下结果:
new DecimalFormat("0.#").format(23.0) // result: "23"
new DecimalFormat(".#").format(23.0) // result: "23.0"
我本以为这两种情况的结果都是 23
,因为特殊字符 #
省略了零。前导特殊字符 0
如何影响小数部分? (尝试 match/understand 使用 javadoc 中给出的 BNF,但失败了。)
根据JavaDoc,第二种格式似乎是无效的,但无论如何它都能正确解析。
Pattern:
PositivePattern
PositivePattern ; NegativePattern
PositivePattern:
Prefixopt Number Suffixopt
NegativePattern:
Prefixopt Number Suffixopt
Prefix:
any Unicode characters except \uFFFE, \uFFFF, and special characters
Suffix:
any Unicode characters except \uFFFE, \uFFFF, and special characters
Number:
Integer Exponentopt
Integer . Fraction Exponentopt
Integer:
MinimumInteger
#
# Integer
# , Integer
MinimumInteger:
0
0 MinimumInteger
0 , MinimumInteger
Fraction:
MinimumFractionopt OptionalFractionopt
MinimumFraction:
0 MinimumFractionopt
OptionalFraction:
# OptionalFractionopt
Exponent:
E MinimumExponent
MinimumExponent:
0 MinimumExponentopt
在这种情况下,我希望格式化程序的行为是未定义的。也就是说,它可能会产生任何旧的东西,我们不能依赖它以任何方式保持一致或有意义。所以,我不知道你为什么得到 23.0,但你可以假设你应该在你的代码中避免它是无稽之谈。
更新:
我只是 运行 一个通过 Java 7 的 DecimalFormat 库的调试器。该代码不仅明确指出“.#”是允许的,其中还有一条注释 (java.text.DecimalFormat:2582-2593) 表明它是允许的,并且还有一个允许它的实现(第 2597 行)。这似乎违反了该模式的文档化 BNF。
鉴于这不是记录在案的行为,您真的不应该依赖它,因为它可能会在 Java 版本甚至库实现之间发生变化。
以下源评论解释了 ".#"
的相当不直观的处理。我的 DecimalFormat.java
文件 (JDK 8) 中的第 3383-3385 行有以下注释:
// Handle patterns with no '0' pattern character. These patterns
// are legal, but must be interpreted. "##.###" -> "#0.###".
// ".###" -> ".0##".
开发人员似乎选择将 ".#"
解释为 ".0##"
,而不是您所期望的 ("0.#"
)。
为什么 java.text.DecimalFormat
评估以下结果:
new DecimalFormat("0.#").format(23.0) // result: "23"
new DecimalFormat(".#").format(23.0) // result: "23.0"
我本以为这两种情况的结果都是 23
,因为特殊字符 #
省略了零。前导特殊字符 0
如何影响小数部分? (尝试 match/understand 使用 javadoc 中给出的 BNF,但失败了。)
根据JavaDoc,第二种格式似乎是无效的,但无论如何它都能正确解析。
Pattern: PositivePattern PositivePattern ; NegativePattern PositivePattern: Prefixopt Number Suffixopt NegativePattern: Prefixopt Number Suffixopt Prefix: any Unicode characters except \uFFFE, \uFFFF, and special characters Suffix: any Unicode characters except \uFFFE, \uFFFF, and special characters Number: Integer Exponentopt Integer . Fraction Exponentopt Integer: MinimumInteger # # Integer # , Integer MinimumInteger: 0 0 MinimumInteger 0 , MinimumInteger Fraction: MinimumFractionopt OptionalFractionopt MinimumFraction: 0 MinimumFractionopt OptionalFraction: # OptionalFractionopt Exponent: E MinimumExponent MinimumExponent: 0 MinimumExponentopt
在这种情况下,我希望格式化程序的行为是未定义的。也就是说,它可能会产生任何旧的东西,我们不能依赖它以任何方式保持一致或有意义。所以,我不知道你为什么得到 23.0,但你可以假设你应该在你的代码中避免它是无稽之谈。
更新: 我只是 运行 一个通过 Java 7 的 DecimalFormat 库的调试器。该代码不仅明确指出“.#”是允许的,其中还有一条注释 (java.text.DecimalFormat:2582-2593) 表明它是允许的,并且还有一个允许它的实现(第 2597 行)。这似乎违反了该模式的文档化 BNF。
鉴于这不是记录在案的行为,您真的不应该依赖它,因为它可能会在 Java 版本甚至库实现之间发生变化。
以下源评论解释了 ".#"
的相当不直观的处理。我的 DecimalFormat.java
文件 (JDK 8) 中的第 3383-3385 行有以下注释:
// Handle patterns with no '0' pattern character. These patterns
// are legal, but must be interpreted. "##.###" -> "#0.###".
// ".###" -> ".0##".
开发人员似乎选择将 ".#"
解释为 ".0##"
,而不是您所期望的 ("0.#"
)。