JDK-8038466 : DecimalFormat with rounding mode regression defect
  • 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-03-26
  • Updated: 2015-05-15
  • Resolved: 2014-03-31
Related Reports
Duplicate :  
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
DecimalFormat rounding is broken

REGRESSION.  Last worked in version 7u51

ADDITIONAL REGRESSION INFORMATION: 
Broken using:
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)

Works using:
java version "1.7.0_17"
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
public class Test {

	public static void main(String[] args) {
		DecimalFormat df = new DecimalFormat("#.00");
		df.setRoundingMode(RoundingMode.HALF_UP);
		final String s = df.format(12.465d);
		if (s.equals("12.47")) {
			System.out.println("All is right with the world");
		} else {
			throw new RuntimeException("Rounding is broken in Java " + System.getProperty("java.version"));
		}
	}
}

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
"All is right with the world"

ACTUAL -
Exception in thread "main" java.lang.RuntimeException: Rounding is broken in Java 1.8.0
	at Test.main(Test.java:32)


REPRODUCIBILITY :
This bug can be reproduced always.

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


public class Test {

	public static void main(String[] args) {
		DecimalFormat df = new DecimalFormat("#.00");
		df.setRoundingMode(RoundingMode.HALF_UP);
		final String s = df.format(12.465d);
		if (s.equals("12.47")) {
			System.out.println("All is right with the world");
		} else {
			throw new RuntimeException("Rounding is broken in Java " + System.getProperty("java.version"));
		}
	}
}

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


Comments
This looks like a known compatibility change in JDK 8 : http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html ==== Area: Core Libs / java.text Synopsis When using the NumberFormat and DecimalFormat classes, the rounding behavior of previous versions of the JDK was wrong in some corner cases. This wrong behaviour happened when calling the format() method with a value that was very close to a tie, where the rounding position specified by the pattern of the NumberFormat or DecimalFormat instance was exactly sitting at the position of the tie. In that case, the wrong double rounding or erroneous non-rounding behavior occurred. As an example, when using the default recommended NumberFormatFormat API form: NumberFormat nf = java.text.NumberFormat.getInstance() followed by nf.format(0.8055d), the value 0.8055d is recorded in the computer as 0.80549999999999999378275106209912337362766265869140625 since this value cannot be represented exactly in the binary format. Here, the default rounding rule is "half-even", and the result of calling format() in JDK 7 is a wrong output of "0.806", while the correct result is "0.805", since the value recorded in memory by the computer is "below" the tie. This new behavior is also implemented for all rounding positions that might be defined by any pattern chosen by the programmer (non default patterns). Nature of Incompatibility behavioral RFE 7131459 ================
27-03-2014