infinidem
asked on
Debug Java BigDecimal in Eclipse
Hi,
I have been debugging some code recently using eclipse and I came across something that I can't explain and wanted to get an answer. The following is a JUnit test that is successful. When I attempted to debug it I get an odd result in the debug screen for csp at the end. I would expect the intCompact to be: 231246....... , but it is -9223372036854775808. Yet the test is successful.
What am I missing?
I have been debugging some code recently using eclipse and I came across something that I can't explain and wanted to get an answer. The following is a JUnit test that is successful. When I attempted to debug it I get an odd result in the debug screen for csp at the end. I would expect the intCompact to be: 231246....... , but it is -9223372036854775808. Yet the test is successful.
What am I missing?
import static org.junit.Assert.assertEquals;
import java.math.BigDecimal;
import org.junit.Test;
public class BigDecimalTest {
@Test
public void Test1() {
BigDecimal opp = new BigDecimal("1.5");
BigDecimal liq = new BigDecimal("1.5");
BigDecimal div = new BigDecimal("0.08");
assertEquals("",2.25d,opp.multiply(liq).doubleValue(),0d);
assertEquals("",1.5d,opp.doubleValue(),0d);
assertEquals("",.12d,opp.multiply(div).doubleValue(),0d);
//Date startDate = new Date("5/9/2013");
//Date endDate = new Date("11/15/2013");
//BigDecimal years = startDate.getYearsBetweenBigDecimal(endDate);
//assertEquals("",5.20547945205479E-01,years.doubleValue(),1E-14);
BigDecimal years = new BigDecimal(5.20547945205479E-01);
BigDecimal dsp = opp.multiply(years).multiply(div);
assertEquals("",6.24657534246575E-02,dsp.doubleValue(),1E-14);
BigDecimal csp = opp.multiply(liq);
csp = csp.add(dsp);
assertEquals("",2.31246575342466E+00,csp.doubleValue(),1E-14);
}
}
ASKER
Interesting. From the rt.jar file I did find this that relates to what Doug said.
Which indicates that the values I am working with did hit the INFLATED threshold. Okay in this example it does quickly go out to 56 decimal points, which would easily put it over the threshold. From the source code I see that it would put it into a BigInteger. Taking a look at the Debug I can see the intCompact is "Set" to inflated which means it is coming from intVal (BigInteger). Then BigInteger is using an array of type int. Which is supposingly in Big Endian. Yet how would 158225327 translate into 231246...
static final long INFLATED = -9223372036854775808L
Which indicates that the values I am working with did hit the INFLATED threshold. Okay in this example it does quickly go out to 56 decimal points, which would easily put it over the threshold. From the source code I see that it would put it into a BigInteger. Taking a look at the Debug I can see the intCompact is "Set" to inflated which means it is coming from intVal (BigInteger). Then BigInteger is using an array of type int. Which is supposingly in Big Endian. Yet how would 158225327 translate into 231246...
csp BigDecimal (id=72)
intCompact -9223372036854775808
intVal BigInteger (id=74)
bitCount 0
bitLength 0
firstNonzeroIntNum 0
lowestSetBit 0
mag (id=75)
[0] 158225327
[1] -1753700659
[2] 1201931299
[3] -1388385198
[4] -1612795011
[5] 446100184
signum 1
precision 0
scale 56
stringCache "2.31246575342465747748832427532761357724666595458984375000" (id=76)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
intCompact is an internal part of the representation which BigDecimal can decide to use when it believes the value can be safely represented as an integer (long actually).
However, if the value being represented by BigDecimal is outside that range (or it believes it may be - such as doing a multiplication) then intCompact may no longer be in use - so checking the value can show you garbage essentially.
At that point, BigDecimal relies on intValue instead, which is itself a BigInteger and intCompact is ignored.
Does that make sense?
If you want to learn more about exactly how BigDecimal is processing these calculations, you can set a breakpoint inside the BigDecimal source code and step through it to see how the multiply and add operations are being implemented in this case.
Hope that helps,
Doug