Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BigDecimal.movePointRight() hangs with very large numbers

The following program freezes, and I can't work out why.

import java.math.*;

public class BigDec {
  public static BigDecimal exp(double z) {
       // Find e^z = e^intPart * e^fracPart.
       return new BigDecimal(Math.E).pow((int)z, MathContext.DECIMAL128).
           multiply(new BigDecimal(Math.exp(z-(int)z)), MathContext.DECIMAL128);
   }

   public static void main(String[] args) {
       // This works OK:
       BigDecimal x = new BigDecimal(3E200);
       System.out.println("x=" + x);
       System.out.println("x.movePointRight(1)=" + x.movePointRight(1));

       // This does not:
       x = exp(123456789);
       System.out.println("x=" + x);
       System.out.println("x.movePointRight(1)=" + x.movePointRight(1)); //hangs
   }
}

For the present purposes, the first method just creates a very large BigDecimal. (Details: it finds e to the power of z, even when this too large to be a double. I am pretty sure this method is correct, though the MathContexts may not be in the best places.)

I know e^123456789 is extremely big, but I really do want to use numbers like this. Any answers would be very gratefully received.

like image 422
Bando Bando Avatar asked Feb 13 '12 11:02

Bando Bando


1 Answers

In fact it does not freeze, but the implementation of movePointRight in Oracle's VM can be extremely inefficient. It is often much faster to multiply or divide with a power of 10 instead of using the movePointRight or movePointLeft methods. In your case, using x.multiply(BigDecimal.TEN) will probably work much better.

like image 182
jarnbjo Avatar answered Oct 05 '22 12:10

jarnbjo