JDK-6876282 : BigDecimal's divide(BigDecimal bd, RoundingFormat r) produces incorrect result
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.math
  • Affected Version: 6u10
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_10
  • CPU: sparc
  • Submitted: 2009-08-26
  • Updated: 2014-12-08
  • Resolved: 2010-12-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u18Fixed 7 b72Fixed OpenJDK6Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
Occurs on JRE 6 updates 14 and 16.  It does not occur for 13 or 05.  Also doesn't occur for JRE 5.  JDK doesnt seem to matter.

ADDITIONAL OS VERSION INFORMATION :
SunOS noc5pbbatchdev2z1 5.10 Generic_137137-09 sun4u sparc SUNW,Sun-Fire-V490

Microsoft Windows XP [Version 5.1.2600]

(Found error on both.)

A DESCRIPTION OF THE PROBLEM :
Doing regression testing with switch from java 5 to java 6 we came across a discrepancy between bigdecimal results of divide.  Based on the javadocs, the three divide method invocations below should correctly round the result up to 0.000115309916.  However, they are not doing that.  They are either rounding down or truncating or otherwise messing up, and are always giving a 5 as the last digit, rather than a 6.  Further investigation determined that this was an issue with JRE 6u14 and u16, but did not occur with JRE6u13 or u05, and jdk doesnt seem to matter.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Get JRE 6u14, or u16. (Good chance everything u14+ will have the bug in it.) Use JDK 6u16 (although i dont believe jdk matters.) Then run the code below.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
div1: 0.000115309915
div2: 0.000115309915
div3: 0.000115309915
ACTUAL -
div1: 0.000115309916
div2: 0.000115309916
div3: 0.000115309916

REPRODUCIBILITY :
This bug can be reproduced rarely.

---------- BEGIN SOURCE ----------
import java.math.*;

public class yy
{

    public static void main(String[] args)
    {
        try {

		BigDecimal one = new BigDecimal("962.430000000000");
		BigDecimal two = new BigDecimal("8346463.460000000000");
		BigDecimal div1 = one.divide(two, 12, RoundingMode.HALF_UP);
		BigDecimal div2 = one.divide(two, RoundingMode.HALF_UP);
		BigDecimal div3 = one.divide(two, new MathContext(9));


		System.out.println("div1: " + div1);
		System.out.println("div2: " + div2);
		System.out.println("div3: " + div3);

	} catch (Exception E) {
		E.printStackTrace();
	}
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
None found yet.

Comments
EVALUATION The root cause is that when we compare the twice of the remainder with the divisor so that we can find out whether we should increment the quotient by 1 or not, we did not consider that twice of the remainder might overflow long.
27-08-2009