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.