6
下面的程序凍結,我無法解決原因。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。 (細節:它發現了z的威力,即使這太大也不能成爲雙倍數。我很確定這種方法是正確的,儘管MathContext可能不在最好的位置。)
我知道e^123456789是非常大的,但我真的很想使用這樣的數字。任何答案將非常感激地收到。
謝謝。這聽起來令人信服,並且'x.multiply(BigDecimal.TEN)'工作正常。我在週末(偶然)離開了我的程序,並且它在星期一早上還沒有完成,所以'movePointRight'不能只是極其低效而且令人難以置信。它所要做的就是將BigDecimal的「比例」改爲1,所以這非常令人費解。 – 2012-02-13 15:22:29
我沒有檢查整個實現,但是在某些時候,movePointXYZ創建了一箇中間BigInteger實例,其大小爲10的次冪(BigDecimal中的位數)。它創建一個帶有前導'1'的字符串(實際上是一個char []),隨後是大約5300萬個'0'字符,並將其傳遞給BigInteger構造函數。然後BigInteger實現嘗試將這個編碼二進制編碼打包到32位塊內部的int數組中,這是實際的罪魁禍首。 – jarnbjo 2012-02-13 18:27:58