On Tue, 23 May 2023 23:16:01 GMT, Justin Lu <j...@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.

I just wonder if it is ok to reverse the rounding/truncation only in this 
special case. If the truncation always comes first, then 0.00 would be correct 
(then 1.01 may be something wrong). Looks to me that the original comment 
suggests it tries to truncate those cases. I suggest filing a CSR for further 
behavioral consideration.

-------------

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

Reply via email to