BigDecimal.add(BigDecimal, MathContext) can return an incorrectly rounded result.
The behaviour changes depending on whether this.precision() has been called beforehand or not.
OPERATING SYSTEM(S):
Windows XP
FULL JDK VERSION(S):
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
DESCRIPTION:
import java.math.*;
class Test {
public static void main(String[] args) {
MathContext mc = new MathContext(1,RoundingMode.DOWN);
BigDecimal a = BigDecimal.valueOf(1999, -1); //value is equivalent to 19990
BigDecimal b = BigDecimal.valueOf(1999, -1);
//Calling precision() should not change behaviour of the BigDecimal
b.precision();
//Adding 1, the unrounded result is 19991, so should round down to 1E+4
BigDecimal resultA = a.add(BigDecimal.ONE, mc);
BigDecimal resultB = b.add(BigDecimal.ONE, mc);
System.out.println(resultA); //prints 1E+4
System.out.println(resultB); //prints 2E+4
}
}
In BigDecimal.add(BigDecimal, MathContext) there is a read from the precision field rather than a call to the precision method.
This causes the change in behaviour depending on whether precision is called or not in the testcase above.
Note that it appears the correct result is obtained when precision() is _not_ called, implying that the logic in BigDecimal.add which uses the precision value might be wrong.