java - BigDecimal.add 奇怪的行为

标签 java bigdecimal fixed-point

方法 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));
}

这是线程转储的一部分:

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)

这是怎么回事?这是错误吗?

最佳答案

好吧,简单回答一下。 BigNumbers 使用字符数组来保持最大精度。由于您的号码将由 100000000 位数字组成,因此这将是您的数组的长度。

100.000.000 chars = bytes

如果我没记错的话,这是 100MB。然后你想用它做数学,这开始需要大量阅读;)

如果您打开 BigDecimal 类,您会看到有很多支票,因为这是“字母”而不是数字。

BigDecimal 可用于保持精度,但这样做需要付出一定的代价,这里是内存和处理时间。

编辑:

只有在以某些方式使用实例时才会出现问题,构造函数会将值存储为指数值 1E+***。如果你打印它,这会很好,但如果你问一个数值,这将开始失败。

更准确地说,BigDecimal.bigTenToThe(int) 将接收指数值 (1000000000)。

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

关于java - BigDecimal.add 奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40487561/

相关文章:

java - 从xslt 2.0降级后如何在xslt1.0中编写函数

java - 将 JSON 字符串解析为 JSONArray (Android)

java - 对于大输入,小数扩展程序运行速度非常慢

java - BigDecimal.add() 被忽略

ada - 单独指定 'Small and ' Delta 是否有意义?

fixed-point - 定点算术

java - 如何按类型从列表中获取对象

java - java.lang.OutOfMemory : GC Overhead limit exceeded vs. java.lang.OutOfMemory: Multicast listener 有什么区别

java - 对 double 值进行减法时未得到预期结果

floating-point - 如何将压缩整数 (16.16) 定点转换为 float ?