JDK-6446965 : Using BigDecimal.divideToIntegralValue with extreme scales can lead to an incorrect result
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.math
  • Affected Version: 5.0u8
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: other
  • Submitted: 2006-07-07
  • Updated: 2013-09-05
  • Resolved: 2013-07-31
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 8
8 b106Resolved
Related Reports
Duplicate :  
Relates :  
Description
OPERATING SYSTEM(S):
Windows XP

FULL JDK VERSION(S):
java version "1.5.0_08-ea"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_08-ea-b01)
Java HotSpot(TM) Client VM (build 1.5.0_08-ea-b01, mixed mode)

DESCRIPTION:
If the scale of the dividend approaches Integer.MIN_VALUE, or the scale of the divisor approaches Integer.MAX_VALUE, in some cases the result is incorrectly evaluated to 0:

Testcase:
public class BDDivideIssue {
	public static void main(String[] args) {
		BigDecimal big   = BigDecimal.valueOf(1, Integer.MIN_VALUE);
	    	BigDecimal small = BigDecimal.valueOf(1, -1);
    		System.out.println(String.format("Integral value of %s / %s? Expecting 1E+%d", big, small, (-(long)Integer.MIN_VALUE-1)));
	    	System.out.println("Obtained: " + big.divideToIntegralValue(small));
	}
}

Output:
Integral value of 1E+2147483648 / 1E+1? Expecting 1E+2147483647
Obtained: 0E+2147483648

The issue is partly caused by an overflow in BigDecimal.compareTo(), where:
	int aethis = this.precision() - this.scale;    // [-1]
	int aeval  =  val.precision() - val.scale;     // [-1]
should be:
	long aethis = (long)this.precision() - this.scale;    // [-1]
	long aeval  =  (long)val.precision() - val.scale;     // [-1]


However, this fix leads the testcase to fail with:
Exception in thread "main" java.lang.ArithmeticException: Underflow
	at java.math.BigDecimal.checkScale(BigDecimal.java:3366)
	at java.math.BigDecimal.divide(BigDecimal.java:1314)
	at java.math.BigDecimal.divide(BigDecimal.java:1597)
	at java.math.BigDecimal.divideToIntegralValue(BigDecimal.java:1649)
	[...]

So, now that we are attempting to carry out the division, it appears we are running into a limitation of the division algorithm.

Comments
Problems with overflowing the int range underly both this issue and the older JDK-6378503 hence resolving this as a duplicate of the older bug.
31-07-2013

EVALUATION Should be fixed.
07-07-2006