BigDecimal.movePointRight() 因数字非常大而挂起

发布于 2025-01-05 04:19:13 字数 923 浏览 4 评论 0原文

下面的程序冻结了,我不知道为什么。

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 非常大,但我真的很想使用这样的数字。如有任何答复,我们将不胜感激。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半步萧音过轻尘 2025-01-12 04:19:13

事实上它不会冻结,但 Oracle VM 中 movePointRight 的实现效率可能极低。使用 10 的幂进行乘法或除法通常比使用 movePointRightmovePointLeft 方法要快得多。在您的情况下,使用 x.multiply(BigDecimal.TEN) 可能会效果更好。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文