BigDecimal.movePointRight() 因数字非常大而挂起
下面的程序冻结了,我不知道为什么。
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实上它不会冻结,但 Oracle VM 中
movePointRight
的实现效率可能极低。使用 10 的幂进行乘法或除法通常比使用movePointRight
或movePointLeft
方法要快得多。在您的情况下,使用 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 themovePointRight
ormovePointLeft
methods. In your case, usingx.multiply(BigDecimal.TEN)
will probably work much better.