-
Bug
-
Resolution: Not an Issue
-
P3
-
None
-
8u25
-
x86_64
-
windows_7
FULL PRODUCT VERSION :
windows:
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
linux:
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Windows 7 64bit, Java8u25
Xubuntu 64bit, Kernel 3.13.0-37-generic, Java8u20
A DESCRIPTION OF THE PROBLEM :
Using DecimalFormat with RoundingMode.HALF_UP doesn't round correct. On tie-breaking or above the digit isn't rounded up.
For example: When one digit in the fraction is needed I assume following values:
1.17 ~~ 1.2
1.19 ~~ 1.2
1.49 ~~ 1.5
These values could be produced by Java7 but not in Java8. This is really bad because RoundingMode HALF_UP is used for commercial rounding of almost all.
REGRESSION. Last worked in version 7u71
ADDITIONAL REGRESSION INFORMATION:
not ready to hand for windows
linux:
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) 64-Bit Server VM (build 22.0-b10, mixed mode)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Instantiate NumberFormatter
2. Set the rounding mode to HALF-UP
3. add fraction digits to round - don't round to whole digits
3. try to format values without zero as integer and without zero left of the rounding position
fe:
0.55 ~~ 0.6 << this works
1.55 ~~ 1.6 << this doesn't work, Java8 calculates 1.5
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
1.17d should be rounded to 1.2
1.55d should be rounded to 1.6
ACTUAL -
1.17 have been rounded to 1.1
1.55 have been rounded to 1.5
ERROR MESSAGES/STACK TRACES THAT OCCUR :
no error
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import org.junit.Test;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import static org.junit.Assert.assertEquals;
public class Java8roundings {
private final DecimalFormat OUT = buildFormatter();
@Test
public void testSpecificValue() {
assertEquals("1,2", OUT.format(1.17d));
}
@Test
public void shouldRoundGivenValuesFromJavadocDividedByTen() {
assertEquals("0,6", OUT.format(0.55d));
assertEquals("0,3", OUT.format(0.25d));
assertEquals("0,2", OUT.format(0.16d));
assertEquals("0,1", OUT.format(0.11d));
assertEquals("-0,1", OUT.format(-0.11d));
assertEquals("-0,3", OUT.format(-0.25d));
assertEquals("-0,6", OUT.format(-0.55d));
}
@Test
public void shouldRoundGivenValuesFromJavadocDividedByTenAddOne() {
assertEquals("1,6", OUT.format(1.55d));
assertEquals("1,3", OUT.format(1.25d));
assertEquals("1,2", OUT.format(1.16d));
assertEquals("1,1", OUT.format(1.11d));
assertEquals("-1,1", OUT.format(-1.11d));
assertEquals("-1,3", OUT.format(-1.25d));
assertEquals("-1,6", OUT.format(-1.55d));
}
@Test
public void checkValuesAroundTheSpecificValue() {
assertEquals("1,1", OUT.format(1.14d));
assertEquals("1,2", OUT.format(1.15d));
assertEquals("1,2", OUT.format(1.16d));
assertEquals("1,2", OUT.format(1.18d));
assertEquals("1,2", OUT.format(1.19d));
assertEquals("1,2", OUT.format(1.20d));
}
@Test
public void useHigherValues() {
assertEquals("1,5", OUT.format(1.49d));
assertEquals("1,6", OUT.format(1.55d));
}
private DecimalFormat buildFormatter() {
final DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.GERMANY);
formatter.setRoundingMode(RoundingMode.HALF_UP); // that's what we want to test
formatter.applyPattern("0.0");
return formatter;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Downgrade to Java7u71
windows:
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
linux:
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Windows 7 64bit, Java8u25
Xubuntu 64bit, Kernel 3.13.0-37-generic, Java8u20
A DESCRIPTION OF THE PROBLEM :
Using DecimalFormat with RoundingMode.HALF_UP doesn't round correct. On tie-breaking or above the digit isn't rounded up.
For example: When one digit in the fraction is needed I assume following values:
1.17 ~~ 1.2
1.19 ~~ 1.2
1.49 ~~ 1.5
These values could be produced by Java7 but not in Java8. This is really bad because RoundingMode HALF_UP is used for commercial rounding of almost all.
REGRESSION. Last worked in version 7u71
ADDITIONAL REGRESSION INFORMATION:
not ready to hand for windows
linux:
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) 64-Bit Server VM (build 22.0-b10, mixed mode)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Instantiate NumberFormatter
2. Set the rounding mode to HALF-UP
3. add fraction digits to round - don't round to whole digits
3. try to format values without zero as integer and without zero left of the rounding position
fe:
0.55 ~~ 0.6 << this works
1.55 ~~ 1.6 << this doesn't work, Java8 calculates 1.5
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
1.17d should be rounded to 1.2
1.55d should be rounded to 1.6
ACTUAL -
1.17 have been rounded to 1.1
1.55 have been rounded to 1.5
ERROR MESSAGES/STACK TRACES THAT OCCUR :
no error
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import org.junit.Test;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import static org.junit.Assert.assertEquals;
public class Java8roundings {
private final DecimalFormat OUT = buildFormatter();
@Test
public void testSpecificValue() {
assertEquals("1,2", OUT.format(1.17d));
}
@Test
public void shouldRoundGivenValuesFromJavadocDividedByTen() {
assertEquals("0,6", OUT.format(0.55d));
assertEquals("0,3", OUT.format(0.25d));
assertEquals("0,2", OUT.format(0.16d));
assertEquals("0,1", OUT.format(0.11d));
assertEquals("-0,1", OUT.format(-0.11d));
assertEquals("-0,3", OUT.format(-0.25d));
assertEquals("-0,6", OUT.format(-0.55d));
}
@Test
public void shouldRoundGivenValuesFromJavadocDividedByTenAddOne() {
assertEquals("1,6", OUT.format(1.55d));
assertEquals("1,3", OUT.format(1.25d));
assertEquals("1,2", OUT.format(1.16d));
assertEquals("1,1", OUT.format(1.11d));
assertEquals("-1,1", OUT.format(-1.11d));
assertEquals("-1,3", OUT.format(-1.25d));
assertEquals("-1,6", OUT.format(-1.55d));
}
@Test
public void checkValuesAroundTheSpecificValue() {
assertEquals("1,1", OUT.format(1.14d));
assertEquals("1,2", OUT.format(1.15d));
assertEquals("1,2", OUT.format(1.16d));
assertEquals("1,2", OUT.format(1.18d));
assertEquals("1,2", OUT.format(1.19d));
assertEquals("1,2", OUT.format(1.20d));
}
@Test
public void useHigherValues() {
assertEquals("1,5", OUT.format(1.49d));
assertEquals("1,6", OUT.format(1.55d));
}
private DecimalFormat buildFormatter() {
final DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.GERMANY);
formatter.setRoundingMode(RoundingMode.HALF_UP); // that's what we want to test
formatter.applyPattern("0.0");
return formatter;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Downgrade to Java7u71
- relates to
-
JDK-8039915 Wrong NumberFormat.format() HALF_UP rounding when last digit exactly at rounding position greater than 5
- Closed
-
JDK-7131459 [Fmt-De] DecimalFormat produces wrong format() results when close to a tie
- Closed
-
JDK-8061380 Wrong NumberFormat.format() HALF_UP rounding when last digit exactly at rounding position greater than 5
- Resolved