Search code examples
javabigdecimal

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.


Solution

  • 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.