Method BigDecimal.add
takes a long time when one argument has a big exponent (9 digits), and the second has an exponent with the different length. I've waited for more than 5 minutes, and it was still going on and on.
Here's code:
@Test
public void testAddBig() throws Exception {
MathContext mc = new MathContext(10, RoundingMode.HALF_UP);
BigDecimal v1 = new BigDecimal("1E+100000000", mc);
BigDecimal v2 = new BigDecimal("1", mc);
System.out.println(v1.add(v2));
}
Here's part of thread dump:
at java.math.BigInteger.square(BigInteger.java:1884)
at java.math.BigInteger.squareKaratsuba(BigInteger.java:1975)
at java.math.BigInteger.square(BigInteger.java:1888)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2011)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2006)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2012)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2010)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2006)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2012)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2011)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.pow(BigInteger.java:2263)
at java.math.BigDecimal.bigTenToThe(BigDecimal.java:3543)
at java.math.BigDecimal.bigMultiplyPowerTen(BigDecimal.java:4508)
at java.math.BigDecimal.add(BigDecimal.java:4443)
at java.math.BigDecimal.add(BigDecimal.java:1289)
What is going on? Is this a bug?
Well, to answer this simply. BigNumbers are working with array of character to keep the precision at the maximum. Since you number will be composed of 100000000 digits, this will be the length of your array.
100.000.000 chars = bytes
This is 100MB if I am not mistaken. Then you want to do math with that, this start to be a lot of reading ;)
If you open the BigDecimal class, you will see that there is a lot of checks since this is "letter" and not numbers.
BigDecimal are usefull to keep precision but this is done at some cost, here memory and time of processing.
EDIT :
This will only be a problem if you use the instance in some ways, the constructor will store the value as a exponent value 1E+***. If you print it this will be fine but if you ask a numerical value, this will start to failed.
To be more precise, BigDecimal.bigTenToThe(int)
will receive the exponent value (1000000000).
private static BigInteger bigTenToThe(int n) {
...
char tenpow[] = new char[n + 1];
....
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With