BigDecimal.add奇怪的行为

VMN*_*VMN 13 java fixed-point bigdecimal

BigDecimal.add当一个参数具有大指数(9位数)时,方法需要很长时间,而第二个参数具有不同长度的指数.我已经等了5分钟以上,而且还在继续.

这是代码:

@Test
public void testAddBig() throws Exception {
    MathContext mc = new MathContext(10, RoundingMode.HALF_UP);
    BigDecimal v1 = new BigDecimal("1E+100000000", mc);
    BigDecimal v2 = new BigDecimal("1", mc);
    System.out.println(v1.add(v2));
}
Run Code Online (Sandbox Code Playgroud)

这是线程转储的一部分:

at java.math.BigInteger.square(BigInteger.java:1884)
at java.math.BigInteger.squareKaratsuba(BigInteger.java:1975)
at java.math.BigInteger.square(BigInteger.java:1888)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2011)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2006)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2012)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2010)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2006)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2012)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.squareToomCook3(BigInteger.java:2011)
at java.math.BigInteger.square(BigInteger.java:1890)
at java.math.BigInteger.pow(BigInteger.java:2263)
at java.math.BigDecimal.bigTenToThe(BigDecimal.java:3543)
at java.math.BigDecimal.bigMultiplyPowerTen(BigDecimal.java:4508)
at java.math.BigDecimal.add(BigDecimal.java:4443)
at java.math.BigDecimal.add(BigDecimal.java:1289)
Run Code Online (Sandbox Code Playgroud)

到底是怎么回事?这是一个错误吗?

Axe*_*elH 7

好吧,简单地回答这个问题.BigNumbers正在使用字符数组来保持最大精度.由于您的数字将由100000000个数字组成,因此这将是您的数组的长度.

100.000.000个字符=字节

如果我没弄错的话,这是100MB.然后你想用它做数学,这开始是很多阅读;)

如果你打开BigDecimal类,你会发现有很多检查,因为这是"字母"而不是数字.

BigDecimal有助于保持精度,但这是以某种代价完成的,这里是内存和处理时间.

编辑:

如果您在某些方面使用实例,这只会是一个问题,构造函数会将值存储为指数值1E +***.如果你打印它会没问题,但如果你问一个数值,这将开始失败.

更准确地说,BigDecimal.bigTenToThe(int)将获得指数值(1000000000).

private static BigInteger bigTenToThe(int n) {
    ...
    char tenpow[] = new char[n + 1];
    ....
}
Run Code Online (Sandbox Code Playgroud)