United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6876282 BigDecimal's divide(BigDecimal bd, RoundingFormat r) produces incorrect result
6876282 : BigDecimal's divide(BigDecimal bd, RoundingFormat r) produces incorrect result

Details
Type:
Bug
Submit Date:
2009-08-26
Status:
Closed
Updated Date:
2010-12-11
Project Name:
JDK
Resolved Date:
2010-12-11
Component:
core-libs
OS:
solaris_10
Sub-Component:
java.math
CPU:
sparc
Priority:
P2
Resolution:
Fixed
Affected Versions:
6u10
Fixed Versions:
7

Related Reports
Backport:
Backport:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

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.
                                     
2009-08-27



Hardware and Software, Engineered to Work Together