<i18n dev> RFR: 8159023: Engineering notation of DecimalFormat does not work as documented

Naoto Sato naoto at openjdk.org
Mon May 22 20:49:52 UTC 2023

On Sat, 20 May 2023 00:00:42 GMT, Justin Lu <jlu at openjdk.org> wrote:

> Please review this PR which updates the Scientific Notation section of Decimal Format. It aims to resolve [JDK-8159023](https://bugs.openjdk.org/browse/JDK-8159023) as well as [JDK-6282188](https://bugs.openjdk.org/browse/JDK-6282188).
> **Scientific Notation** in Decimal Format contains the definition for a scientific notation formatted number's mantissa as such: _The number of significant digits in the mantissa is the sum of the minimum integer and maximum fraction digits, and is unaffected by the maximum integer digits. For example, 12345 formatted with "##0.##E0" is "12.3E3"._
> Both the definition and example are incorrect, as the actual result is "12.E345". 
> The following example data show that scientific notation formatted numbers do not adhere to that definition. As, according to the definition, the following numbers should have 3 significant digits, but in reality, they have up to 5.
> 123 formatted by ##0.#E0 is 123E0
> 1234 formatted by ##0.#E0 is 1.234E3
> 12345 formatted by ##0.#E0 is 12.34E3
> 123456 formatted by ##0.#E0 is 123.5E3
> 1234567 formatted by ##0.#E0 is 1.235E6
> 12345678 formatted by ##0.#E0 is 12.35E6
> 123456789 formatted by ##0.#E0 is 123.5E6 
> The actual definition of the mantissa, as well as examples and further context are included in this change. In addition, a test has been added that tests various patterns to numbers and ensures the format follows the new definition's mathematical expression.

(a bit of background to others) We did some archaeological work to dig into the history of this spec, and found that the spec was retrofitted to the implementation. (https://bugs.openjdk.org/browse/JDK-4241670). We suspect that this wording was incorrectly interpreted from the impl at that time.

test/jdk/java/text/Format/DecimalFormat/MantissaDigits.java line 56:

> 54:     public void testMantissaDefinition(String pattern) {
> 55:         Locale.setDefault(Locale.ENGLISH);
> 56:         DecimalFormat df = new DecimalFormat(pattern);

Instead of setting the default locale, you could get the explicit format by

new DecimalFormat(pattern, new DecimalFormatSymbols(Locale.US)); // DFS can be a static instance

test/jdk/java/text/Format/DecimalFormat/MantissaDigits.java line 89:

> 87:             // Test the new definition of the Mantissa
> 88:             Integer calculatedDigits = Math
> 89:                     .min(Math.max(zeroes, originalNumDigits), (hashes+zeroes));

Could we make those expected numbers into the `Arguments` so that there is no need to calculate in the test case at runtime? I think that would be more readable.


PR Review: https://git.openjdk.org/jdk/pull/14066#pullrequestreview-1437505357
PR Review Comment: https://git.openjdk.org/jdk/pull/14066#discussion_r1201067500
PR Review Comment: https://git.openjdk.org/jdk/pull/14066#discussion_r1201062733

More information about the i18n-dev mailing list