<i18n dev> RFR: 8174722: Wrong behavior of DecimalFormat with RoundingMode.UP in special case

Joe Darcy darcy at openjdk.org
Tue May 23 23:32:54 UTC 2023

On Tue, 23 May 2023 23:16:01 GMT, Justin Lu <jlu at openjdk.org> wrote:

> Please review this PR, which addresses a case where Decimal Format would violate certain RoundingMode contracts given the right pattern and double.
> For example,
> DecimalFormat df = new DecimalFormat();
> df.setRoundingMode(RoundingMode.UP);
> double small = 0.0001;
> double big = 1.0001;
> df.applyPattern("0.00");
> df.format(small); // returns 0.00, which violates UP
> df.format(big); // returns 1.01, which does not violate UP
> In this example `0.0001` becomes `0.00`, a decrease in magnitude. This violates the RoundingMode.UP contract as RoundingMode.UP states "Note that this rounding mode never decreases the magnitude of the calculated value."
> This edge case is a result of when values smaller than the absolute value of `.1` have more leading zeros between the decimal and the first non-zero digit (_0.0001 -> **3**_) than maximum fractional digits in the pattern (_0.00 -> **2**_).
> The change to Decimal Format ensures that during this case, the rounding mode is considered before truncation, which dictates if the formatted number should insert a 1 in the least significant digit location.
> The test validates the change by using data from larger counterparts. For example, If we are testing `0.0009`, we can format `1.0009` with the same pattern and mode that we use on `0.0009`, then compare the fractional portions to each other and ensure they are equal.

Note there are some hazards here with respect to the numerical values of double and the decimal string used to represent the double; in exact terms:

jshell> new BigDecimal(1.0001)
$2 ==> 1.0000999999999999889865875957184471189975738525390625

jshell> new BigDecimal(0.0001)
$3 ==> 0.000100000000000000004792173602385929598312941379845142364501953125


PR Comment: https://git.openjdk.org/jdk/pull/14110#issuecomment-1560254680

More information about the i18n-dev mailing list