JDK-8174722 : Wrong behavior of DecimalFormat with RoundingMode.UP in special case
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.text
  • Affected Version: 8,9
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2017-02-09
  • Updated: 2025-04-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
CSR :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.14393]

A DESCRIPTION OF THE PROBLEM :
When using java.text.DecimalFormat with RoundingMode.UP there is the following special case in which rounding does produce a wrong result: 
 
I try to format the double value 0.0001 with RoundingMode UP to a String rounded to two decimal place. 

As result I expect the String "0,01" but I get the String "0,00"

When I format the double value 1.0001 with the same options I get the String "1.01" as expected when rounding to two decimal places with RoundingMode UP. 

The first case I mentioned is wrong behaviour. 
UP RoundingMode must not produce a String representing a double value that is smaller than the input double value. The javadoc of RoundingMode.UP says " Note that this rounding mode never decreases the magnitude of the calculated value." which is violated by the special case mentioned above. 

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Code example that shows the bevaviour:

double dVal = 0.0001;
DecimalFormat df = new DecimalFormat();
df.setRoundingMode(RoundingMode.UP);
df.applyPattern("0.00");
String result = df.format(dVal));

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
result should be "0,01"
ACTUAL -
result is "0,00"

REPRODUCIBILITY :
This bug can be reproduced always.


Comments
A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/14110 Date: 2023-05-23 23:16:01 +0000
23-05-2023

This bug is exposed if the value given to DecimalFormat has enough digits to be interpreted in scientific notation and the number of fractional digits in the desired format is less than X in the format of A.B x 10^-X For example, 0.0001 with a format of 0.00 incorrectly produces 0.00 (1.0x10-3 where x is 3, and format is 2 digits) but 0.0001 with a format of 0.000 correctly produces 0.001 (1.0x10-3 where x is 3 and format is 3 digits) The error is exposed in DecimalFormat.subformatNumber()
23-03-2023

Modified the test case provided in the bug report to show the difference in outputs generated by RoundingMode.UP on a double and using BigDecimal.ROUND_UP. Following are the results: JDK 8u121- Fail JDK 9-ea + 153 - Fail Following is the output : 0.00 Rounded value with setting scale = 0.01
10-02-2017