如何比较两个bigdecimal

How to compare two big decimal

我有以下代码,但我无法理解为什么两个 bigdecimal 不被视为相等

class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        BigDecimal b = new BigDecimal(13.90);
        BigDecimal b2 = new BigDecimal("13.9");
        System.out.println(b.compareTo(b2));
    }
}

此代码输出 1 作为输出。为什么会这样呢?不应该是0吗?

此外,如果我写 13.9 而不是“13.9”,它会给出 0 作为输出

因为你假设如果你使用 13.9,它就是 13.9。尝试打印 bb2 的值,你会看到 13.9 实际上是 13.9000000000000003552713678800500929355621337890625,而解析后的字符串值 13.9。所以 b (略)高于 b2.

public static void main(String...strings) {
            BigDecimal b = new BigDecimal(13.9);
            BigDecimal b2 = new BigDecimal("13.9");
            System.out.printf("%s %s %d%n", b, b2, b.compareTo(b2));
}

给出输出:

13.9000000000000003552713678800500929355621337890625 13.9 1

关于浮点数学主题,您可能需要阅读 Why Are Floating Point Numbers Inaccurate? 和 Whosebug 上可用的其他链接。

浮点数值并不精确,它们是近似值。因此,当您键入文字值 13.90 时,保留的实际值并不完全是 13.90,而是尽可能接近它。

BigDecimal 值是精确的,而字符串只是字符串。

因此,当您使用 new BigDecimal(13.90) 和 new BigDecimal("13.9") 时,第一个保存的值恰好是传递给它的浮点值,与 13.9 非常接近但不同。第二个恰好包含 13.9.

其中一个是 13.9,另一个接近但不等于 13.9。所以这两个对象不相等。

BigDecimal 构造函数的javadoc double 说明结果"can be somewhat unpredictable"。那是因为输入的十进制值实际上是一个浮点数的近似值。通常,使用 BigDecimal String 构造函数构造十进制值是一种很好的做法。但是,如果您不这样做或不能这样做,您可以随时设置比例和圆角。下面的代码会给你你想要的结果。

BigDecimal b = new BigDecimal(13.90).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal b2 = new BigDecimal("13.9");
System.out.println(b.compareTo(b2));

注意:四舍五入发生在刻度的末尾。因此,对于一组 2,值 13.900004 将四舍五入为 13.90。