使用equals对比有小数位的Bigdecimal

   public static void main(String[] args) {
        BigDecimal qtyActual = new BigDecimal(0).setScale(2,BigDecimal.ROUND_UP);
        System.out.println(qtyActual.equals(BigDecimal.ZERO));

        qtyActual = new BigDecimal(0);
        System.out.println(new BigDecimal(0).equals(BigDecimal.ZERO));

        qtyActual = new BigDecimal(0);
        System.out.println(new BigDecimal(0.00).equals(BigDecimal.ZERO));
    }

上述代码输出的对别结果是false;true;true

虽然qtyActual 这个参数的值一直都是0,但是结果却不同,因为BigDecimal的equals方法在对比两个值时会对比两数的小数位数,equals源码如下

 public boolean equals(Object x) {
        if (!(x instanceof BigDecimal))
            return false;
        BigDecimal xDec = (BigDecimal) x;
        if (x == this)
            return true;
        //对比小数位数
        if (scale != xDec.scale)
            return false;
        long s = this.intCompact;
        long xs = xDec.intCompact;
        if (s != INFLATED) {
            if (xs == INFLATED)
                xs = compactValFor(xDec.intVal);
            return xs == s;
        } else if (xs != INFLATED)
            return xs == compactValFor(this.intVal);
        return this.inflated().equals(xDec.inflated());
    }

所以,第一个输出结果位false和第二个输出结果为true就可以解释通了,但是第三个比较代码0.00 和 0的小数位不同啊,第三个输出语句不应该是false吗?

截取BigDecimal构造方法的一部分

public BigDecimal(double val, MathContext mc) {
        if (Double.isInfinite(val) || Double.isNaN(val))
            throw new NumberFormatException("Infinite or NaN");
        // Translate the double into sign, exponent and significand, according
        // to the formulae in JLS, Section 20.10.22.
        long valBits = Double.doubleToLongBits(val);
        int sign = ((valBits >> 63) == 0 ? 1 : -1);
        int exponent = (int) ((valBits >> 52) & 0x7ffL);
        long significand = (exponent == 0
                ? (valBits & ((1L << 52) - 1)) << 1
                : (valBits & ((1L << 52) - 1)) | (1L << 52));
        exponent -= 1075;
        // At this point, val == sign * significand * 2**exponent.

        /*
         * Special case zero to supress nonterminating normalization and bogus
         * scale calculation.
         */
        if (significand == 0) {
            this.intVal = BigInteger.ZERO;
            this.scale = 0;
            this.intCompact = 0;
            this.precision = 1;
            return;
        }

可以看到this.scale = 0;而 BigDecimal.ZERO的代表的数是scale为0的数,所以第三个对比结果为true

 BigDecimal类型数的值对比可以使用compareTo(),两数相同返回0

发布了56 篇原创文章 · 获赞 67 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/leo187/article/details/99969579