JDK-8041961 : DecimalFormat RoundingMode.HALF_UP is broken (HALF_EVEN is OK)
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.text
  • Affected Version: 8
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2014-04-24
  • Updated: 2014-10-09
  • Resolved: 2014-05-07
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) Client VM (build 25.5-b02, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
When formatting with BigDecimal and a configured maximum number of fraction digits, the HALF_UP RoundingMode returns wrong results for some numbers. HALF_EVEN works as expected.

Please note that this is NOT just the JDK8 rounding change as mentioned in the compatibility notes -- this rounding is fundamentally broken. In my example I have a smaller number rounding up, and the larger number rounding down.

REGRESSION.  Last worked in version 7u51

ADDITIONAL REGRESSION INFORMATION: 
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) Client VM (build 24.51-b03, mixed mode, sharing)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
As per source code:
create a new DecimalFormat, set the maximum fraction digits, set rounding mode to half_up, and format various numbers.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
HALF_UP
99.9989 -> 100
99.999 -> 100
HALF_EVEN
99.9989 -> 100
99.999 -> 100

ACTUAL -
HALF_UP
99.9989 -> 100
99.999 -> 99.99
HALF_EVEN
99.9989 -> 100
99.999 -> 100


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.math.RoundingMode;
import java.text.DecimalFormat;

public class Decimal {
    public static void main(String[] args) {
        DecimalFormat format = new DecimalFormat();
        format.setMaximumFractionDigits(2);
        format.setRoundingMode(RoundingMode.HALF_UP);
        System.out.println("HALF_UP");
        System.out.println(99.9989+" -> "+format.format(99.9989));
        System.out.println(99.9990 + " -> " + format.format(99.9990));
        format.setRoundingMode(RoundingMode.HALF_EVEN);
        System.out.println("HALF_EVEN");
        System.out.println(99.9989+" -> "+format.format(99.9989));
        System.out.println(99.9990+" -> "+format.format(99.9990));
    }
}

---------- END SOURCE ----------


Comments
Hi Naoto. Thanks for the triage. I just investigated further the problem, and found it is definitely a duplicate of 8039915 as you noticed. Thus flagging it as such
07-05-2014

Hi Olivier, Just reading the description, and it sounds like similar to the one you are looking into right now. So I am assigning this to you too, but please feel free to assign back if it's not related. Thanks!
25-04-2014