-
Bug
-
Resolution: Not an Issue
-
P3
-
8, 9
-
generic
-
generic
FULL PRODUCT VERSION :
java version "1.8.0_40-ea"
Java(TM) SE Runtime Environment (build 1.8.0_40-ea-b15)
Java HotSpot(TM) Client VM (build 25.40-b18, mixed mode, sharing)
also reproduced on 1.8.0-25
ADDITIONAL OS VERSION INFORMATION :
Windows 7 Enterprise SP 1
A DESCRIPTION OF THE PROBLEM :
The DecimalFormat percent-formatter produces the wrong result when rounding-halves up for a double representing 12.235% i.e. 0.12235.
Please note that this is not a symptom of the Java 8 bug fix to round values close to "a half" based on their internal representation. Assuming the value displayed by BigDecimal.toString is a correct representation of the internals of the "double", the internal value of the problem number is actually slightly larger than 0.12235, so even with the Java 8 fix, this value should "round up".
REGRESSION. Last worked in version 7u51
ADDITIONAL REGRESSION INFORMATION:
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) Client VM (build 24.45-b08, mixed mode, sharing)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the Demo program in English Locale.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Double is 0.12235
Internal representation is larger than this... 0.12235000000000000042188474935755948536098003387451171875
...but DecimalFormat rounds down 12.24%
...can work around by formatting the BigDecimal 12.24%
ACTUAL -
Double is 0.12235
Internal representation is larger than this... 0.12235000000000000042188474935755948536098003387451171875
...but DecimalFormat rounds down 12.23%
...can work around by formatting the BigDecimal 12.24%
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class Demo
{
public static void main( final String[] args )
{
final NumberFormat nf = DecimalFormat.getPercentInstance();
nf.setMinimumFractionDigits( 2 );
nf.setMaximumFractionDigits( 2 );
nf.setRoundingMode( RoundingMode.HALF_UP );
final double problem = 0.122350d; // expect this to round up to 12.24%
System.out.println("Double is " + problem );
System.out.println( "Internal representation is larger than this... " + new BigDecimal(problem));
System.out.println(" ...but DecimalFormat rounds down " + nf.format(problem) );
System.out.println(" ...can work around by formatting the BigDecimal " + nf.format(new BigDecimal(problem)) );
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
As shown in the code, wrapping the double in a BigDecimal before formatting seems to work around the problem.
java version "1.8.0_40-ea"
Java(TM) SE Runtime Environment (build 1.8.0_40-ea-b15)
Java HotSpot(TM) Client VM (build 25.40-b18, mixed mode, sharing)
also reproduced on 1.8.0-25
ADDITIONAL OS VERSION INFORMATION :
Windows 7 Enterprise SP 1
A DESCRIPTION OF THE PROBLEM :
The DecimalFormat percent-formatter produces the wrong result when rounding-halves up for a double representing 12.235% i.e. 0.12235.
Please note that this is not a symptom of the Java 8 bug fix to round values close to "a half" based on their internal representation. Assuming the value displayed by BigDecimal.toString is a correct representation of the internals of the "double", the internal value of the problem number is actually slightly larger than 0.12235, so even with the Java 8 fix, this value should "round up".
REGRESSION. Last worked in version 7u51
ADDITIONAL REGRESSION INFORMATION:
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) Client VM (build 24.45-b08, mixed mode, sharing)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the Demo program in English Locale.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Double is 0.12235
Internal representation is larger than this... 0.12235000000000000042188474935755948536098003387451171875
...but DecimalFormat rounds down 12.24%
...can work around by formatting the BigDecimal 12.24%
ACTUAL -
Double is 0.12235
Internal representation is larger than this... 0.12235000000000000042188474935755948536098003387451171875
...but DecimalFormat rounds down 12.23%
...can work around by formatting the BigDecimal 12.24%
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class Demo
{
public static void main( final String[] args )
{
final NumberFormat nf = DecimalFormat.getPercentInstance();
nf.setMinimumFractionDigits( 2 );
nf.setMaximumFractionDigits( 2 );
nf.setRoundingMode( RoundingMode.HALF_UP );
final double problem = 0.122350d; // expect this to round up to 12.24%
System.out.println("Double is " + problem );
System.out.println( "Internal representation is larger than this... " + new BigDecimal(problem));
System.out.println(" ...but DecimalFormat rounds down " + nf.format(problem) );
System.out.println(" ...can work around by formatting the BigDecimal " + nf.format(new BigDecimal(problem)) );
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
As shown in the code, wrapping the double in a BigDecimal before formatting seems to work around the problem.
- relates to
-
JDK-8066414 DecimalFormat multiplier attribute implementation for double values close to tie causes rounding errors
- Closed