Why does java.text.DecimalFormat
evaluate the following results:
new DecimalFormat("0.#").format(23.0) // result: "23"
new DecimalFormat(".#").format(23.0) // result: "23.0"
I would have expected the result to be 23
in both cases, because special character #
omits zeros. How does the leading special character 0
affect the fraction part? (Tried to match/understand it with the BNF given in javadoc, but failed to do so.)
DecimalFormat parses all Unicode characters that represent decimal digits, as defined by Character. digit() . In addition, DecimalFormat also recognizes as digits the ten consecutive characters starting with the localized zero digit defined in the DecimalFormatSymbols object.
Just use %. 2f as the format specifier. This will make the Java printf format a double to two decimal places. /* Code example to print a double to two decimal places with Java printf */ System.
The "D" (or decimal) format specifier converts a number to a string of decimal digits (0-9), prefixed by a minus sign if the number is negative. This format is supported only for integral types. The precision specifier indicates the minimum number of digits desired in the resulting string.
DecimalFormat isn't thread-safe, thus we should pay special attention when sharing the same instance between threads.
The second format seems to be invalid according to the JavaDoc, but somehow it parses without error anyway.
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
In this case I'd expect the behaviour of the formatter to be undefined. That is, it may produce any old thing and we can't rely on that being consistent or meaningful in any way. So, I don't know why you're getting the 23.0, but you can assume that it's nonsense that you should avoid in your code.
Update: I've just run a debugger through Java 7's DecimalFormat library. The code not only explicitly says that '.#' is allowed, there is a comment in there (java.text.DecimalFormat:2582-2593) that says it's allowed, and an implementation that allows it (line 2597). This seems to be in violation of the documented BNF for the pattern.
Given that this is not documented behaviour, you really shouldn't rely on it as it's liable to change between versions of Java or even library implementations.
The following source comment explains the rather unintuitive handling of ".#"
. Lines 3383-3385 in my DecimalFormat.java
file (JDK 8) have the following comment:
// Handle patterns with no '0' pattern character. These patterns
// are legal, but must be interpreted. "##.###" -> "#0.###".
// ".###" -> ".0##".
Seems like the developers have chosen to interpret ".#"
as ".0##"
, instead of what you expected ("0.#"
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With