Details
Backports
Issue  Fix Version  Assignee  Priority  Status  Resolution  Resolved In Build 

JDK8000978  7u40  Olivier Lagneau  P4  Closed  Fixed  b13 
Description
double myDouble = ....;
NumberFormat nf = NumberFormat.getInstance(); // or NumberFormat.getCurrencyInstance()
String myStr = nf.format(myDouble);
the returned string from format(...) will be sometimes wrong when
the passed double value is close to a tie (like 1.3905d for example).
Such values are writen in decimal radix as :
"iiiiii.ff5" in the currency case (getCurrencyInstance()), i.e. 2 fractional digits.
or
"iiiiiiii.fff5" in the decimal case (getInstance()), i.e. 3 fractional digits.
where 'i' represents an integral digit and 'f' represents a fractional digit.
Example of such value are:
0.8055d, 1.1015d, 1.1835d, 7.9005d. There are a lot of them.
These kind of values cannot be represented exactly with the double floatingpoint encoding format.
So only an approximation of them is recorded in memory:
0.8055d => exact value = 0.80549999999999999378275106209912337362766265869140625
1.1015d => exact value = 1.1014999999999999236166559057892300188541412353515625
1.1835d => exact value = 1.183499999999999996447286321199499070644378662109375
7.9005d => exact value = 7.90050000000000007815970093361102044582366943359375
nf.format(0.8055d); will return "0.806" where it should return "0.805" (see exact value above)
nf.format(1.1015d); will return "1.102" where it should return "1.101" (see exact value above)
nf.format(1.1835d); will return "1.184" where it should return "1.183" (see exact value above)
nf.format(7.9005d); will return "7.9" where it should return "7.901" (see exact value above)
This will also happen if DecimalFormat instance has not been created using the default usage pattern.
For example, if the associated pattern requires 5 digits after decimal point when the value is close
to a tie from the rounding standpoint (fractional part like "fffff5").
This may be impacting (at from the enduser standpoint) with series of '9' digits:
like format(9.9995d) returning "10" where it may have to return "9.999".
Try the small following program that shows the wrong behavior:
public static void main(String[] args) {
java.text.NumberFormat nf = java.text.NumberFormat.getInstance();
double aDouble;
String myStr;
aDouble = 0.8055d;
myStr = nf.format(aDouble);
System.out.println("format(" + aDouble + ") returns \"" + myStr + "\" where it should return \"0.805\".");
aDouble = 1.1015d;
myStr = nf.format(aDouble);
System.out.println("format(" + aDouble + ") returns \"" + myStr + "\" where it should return \"1.101\".");
aDouble = 1.1835d;
myStr = nf.format(aDouble);
System.out.println("format(" + aDouble + ") returns \"" + myStr + "\" where it should return \"1.183\".");
aDouble = 7.9005d;
myStr = nf.format(aDouble);
System.out.println("format(" + aDouble + ") returns \"" + myStr + "\" where it should return \"7.901\".");
}
Issue Links
 duplicates

JDK8038466 DecimalFormat with rounding mode regression defect

JDK8080463 DecimalFormat  rounding behaviour different from Java 6 and 7

JDK8038466 DecimalFormat with rounding mode regression defect
 relates to

JDK8066560 Formatter printf rounding error (double rounding up) for double values close to but below tie

JDK8057170 [FmtDe] DecimalFormat produces wrong format() results in a few non HALF_* corner cases

JDK8029896 Regression in NumberFormat rounding from 1.7 to 1.8. Rounding no longer works.

JDK8039915 Wrong NumberFormat.format() HALF_UP rounding when last digit exactly at rounding position greater than 5

JDK8062013 DecimalFormat / rounding / HALF_UP

JDK8062756 Rounding HALF_UP produce wrong text representations

JDK6609637 [FmtNu] Rounding error of class java.text.DecimalFormat with #0.00 pattern

JDK8059861 Modifications to NumberFormat format() caused new rounding errors

JDK8041961 DecimalFormat RoundingMode.HALF_UP is broken (HALF_EVEN is OK)

JDK7050528 Improve performance of java.text.DecimalFormat.format() call stack

JDK8046167 JEP 177: Optimize java.text.DecimalFormat.format
User: darcy
Date: 20130111 23:39:32 +0000