bigdecimal add函数显示值不正确

ioekq8ef  于 2021-06-27  发布在  Java
关注(0)|答案(2)|浏览(657)

我有以下代码:

AtomicReference<BigDecimal> totalAmount = new AtomicReference<>(new BigDecimal(BigInteger.ZERO, new MathContext(3)));
List<BigDecimal> list = new ArrayList<BigDecimal>();
list.add(new BigDecimal(8024));
list.add(new BigDecimal(8024));

list.forEach(value -> {

    totalAmount.set(totalAmount.get().add(value, new MathContext(3)));
});

基本上当我运行上述代码时,总金额的总和应该是 16048 但实际上是1.60e+4。请告诉我我在这里缺少什么来得到正确的数额?

xxslljrj

xxslljrj1#

你似乎错过了两件事:
对于值:使用 new MathContext(3) 加法时,使值四舍五入为三位数。首先你加8024,和8024,四舍五入到8020。前三位以外的所有数字都设置为0,向上或向下舍入。然后再加8024,和16044,四舍五入到16000。
对于输出格式:打印 BigDecimal ,您正在(隐式或显式)调用 toString 方法。这种方法经常产生你得到的科学符号。确切的规则在文档中,请参阅底部的链接。如果您想确保控制 BigDecimal ,使用 DecimalFormat .
与本例中不需要的输出无关:您使用不当 AtomicReference 当你第一次做 get() 然后是一个 set() . 在多线程环境中(这是 AtomicReference 有任何意义)一个不同的线程可以做一个 set() 或者在这两个调用之间执行其他操作,但这样做的结果会丢失 set() . 相反,你应该使用 accumulateAndGet (或 getAndAccumulate )方法 AtomicReference .
我也不明白你为什么这么复杂。这种简单的方法可以满足您的要求:

List<BigDecimal> list = List.of(new BigDecimal("8024"), new BigDecimal("8024"));

    BigDecimal totalAmount = BigDecimal.ZERO;
    for (BigDecimal value : list) {
        totalAmount = totalAmount.add(value);
    }
    System.out.println(totalAmount);

输出为:
16048
这与另一个答案中的代码相似。
编辑:作为一个好习惯,我将字符串文字传递给 new BigDecimal() . 虽然传递一个整数文本(如8024)本身没有问题,但传递一个双精度文本(如8024.1)通常意味着不准确。传递一根线总会给你一个答案 BigDecimsl 与字符串保持完全相同的值。
文档链接 BigDecimal.toString() DecimalFormat AtomicReference.accumulateAndGet()

new9mtju

new9mtju2#

BigDecimal 以及它的 add() 方法将产生所需的结果。这里不需要使用lambda表达式。下面的代码演示了相同的情况。这也是干净的代码。

public static void main(String[] args) {

        List<BigDecimal> list = new ArrayList<BigDecimal>();

        list.add(new BigDecimal(8024));
        list.add(new BigDecimal(8024));

        BigDecimal total = BigDecimal.ZERO;

        for(BigDecimal element : list)
            total = total.add(element);

        System.out.print("Sum : " + total);
}

请在ideone.com上查看此代码的实时运行。
总数:16048

相关问题