BigDecimal.movePointRight () зависает с очень большими числами - PullRequest
6 голосов
/ 13 февраля 2012

Следующая программа зависает, и я не могу понять, почему.

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
   }
}

Для настоящих целей первый метод просто создает очень большой BigDecimal.(Подробности: он находит e в степени z, даже когда он слишком велик, чтобы быть двойным. Я почти уверен, что этот метод верен, хотя MathContexts могут быть не в лучших местах.)Я знаю, что e ^ 123456789 очень большой, но я действительно хочу использовать числа, подобные этой.Любые ответы будут очень благодарны.

1 Ответ

4 голосов
/ 13 февраля 2012

На самом деле он не останавливается, но реализация movePointRight в виртуальной машине Oracle может быть крайне неэффективной.Часто гораздо быстрее умножать или делить со степенью 10 вместо использования методов movePointRight или movePointLeft.В вашем случае использование x.multiply(BigDecimal.TEN), вероятно, будет работать намного лучше.

...