前言

BigDecimal 是 java.math 包中提供的一种可以用来进行精确运算的类型。所以,在支付、电商等业务中,BigDecimal 的使用非常频繁。而且其内部自带了很多方法,如加,减,乘,除等运算方法都是可以直接调用的。除了需要用 BigDecimal 表示数字和进行数字运算以外,代码中还经常需要对于数字进行相等判断。

说到等值比较,咱们先看看《阿里巴巴Java开发手册》中的要求:

大聪明教你学Java | 为什么不能使用 BigDecimal 的 equals 方法做等值比较
那么为什么会有这样的要求呢~ 其中的奥秘是什么呢~ 请各位小伙伴听我娓娓道来…

BigDecimal 做等值比阿里巴巴1688货源批发官网

    public static void main(String[] args) {
        BigDecimal bigDecimal1 = new BigDecimal(1);
        BigDecimal bigDecimal2 = new BigDecimal(1);
        if(bigDecimal1 == bigDecimal2){
            //等值比较
        }
    }

相信聪明的小伙伴一眼就可以看出来上面的代码源码是什么意思是有问题的,因为阿里众包 BigDecimal 是对象,不能使用 == 来做等源码交易平台值判断。

如果我们使用 BigDecimal 的阿里云 equals 方法做等Java值比较是不是可以呢?

    public static void main(String[] args) {
        BigDecimal bigDecimal1 = new BigDecimal(1);
        BigDecimal bigDecimal2 = new BigDecimal(1);
        if(bigDecimal1.equals(bigDecimal2)){
            //等值比较
        }
    }

这里我先卖个关子,咱们跑跑代码来看看能不阿里巴巴招聘能用 BigDecima阿里巴巴网页版l 的 equals 方法做等值比较(●’◡’●),

    public static void main(String[] args) {
        BigDecimal bigDecimal1 = new BigDecimal(1);
        BigDecimal bigDecimal2 = new BigDecimal(1);
        System.out.println(bigDecimal1.equals(bigDecimal2));
        BigDecimal bigDecimal3 = new BigDecimal(1);
        BigDecimal bigDecimal4 = new BigDecimal(1.0);
        System.out.println(bigDecimal3.equals(bigDecimal4));
        BigDecimal bigDecimal5 = new BigDecimal("1");
        BigDecimal bigDecimal6 = new BigDecimal("1.0");
        System.out.println(bigDecimal5.equals(bigDecimal6));
    }

大聪明教你学Java | 为什么不能使用 BigDecimal 的 equals 方法做等值比较
我们可以发现,在使用javascript BigDecimal 的 equalsjava怎么读 方法对 1 和 1.0 进行比较的时候:使用 int、do阿里巴巴下载uble源码编辑器 定义 BigDecimal 结果是 true阿里巴巴网页版;使用 String 定义 BigDecimal 结果是false,为什么会出现这种源码编辑器下载情况呢?

我们一起来看看 equals 方法的源码

	/**
     * Compares this {@code BigDecimal} with the specified
     * {@code Object} for equality.  Unlike {@link
     * #compareTo(BigDecimal) compareTo}, this method considers two
     * {@code BigDecimal} objects equal only if they are equal in
     * value and scale (thus 2.0 is not equal to 2.00 when compared by
     * this method).
     *
     * @param  x {@code Object} to which this {@code BigDecimal} is
     *         to be compared.
     * @return {@code true} if and only if the specified {@code Object} is a
     *         {@code BigDecimal} whose value and scale are equal to this
     *         {@code BigDecimal}'s.
     * @see    #compareTo(java.math.BigDecimal)
     * @see    #hashCode
     */
    @Override
    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());
    }

其实咱们从方法的注释中就能找到答案:equals 方法会比较两部分内容,分别是值(valuejava培训)和标度(scale),也阿里巴巴招聘就是说 bigDecimal5 和 bigDecimal6 的值虽然相同,但是标度是不一样的。

咱们打个断点,debug 一下看看~

大聪明教你学Java | 为什么不能使用 BigDecimal 的 equals 方法做等值比较

我们可以看见 bigDecimal5 的标度值是0,而bigDeci阿里巴巴招聘mal6的标度值是1,所java面试题以 bigDecimal5 和 bigDecimal6 的比较结果是false (●∀●)

阿里么这时候又产生了一个疑问:为什么标度不同呢?

嘻嘻~ 各位小伙伴稍安勿躁,请听我娓娓道来~

BigDecimal 一共有以下 4 个构造方法:

  • BigDecimal(int)
  • BigDecimal(double)
  • BigDecimal(long)
  • BigDecim阿里嘎多al(String)

其中最容易理解的就是 BigDecimal(int) 和 BigDecimal(long),因为是整数,所以标度就是 0 (源码如下):

	/**
     * Translates an {@code int} into a {@code BigDecimal}.  The
     * scale of the {@code BigDecimal} is zero.
     *
     * @param val {@code int} value to be converted to
     *            {@code BigDecimal}.
     * @since  1.5
     */
    public BigDecimal(int val) {
        this.intCompact = val;
        this.scale = 0;
        this.intVal = null;
    }
	/**
     * Translates a {@code long} into a {@code BigDecimal}.  The
     * scale of the {@code BigDecimal} is zero.
     *
     * @param val {@code long} value to be converted to {@code BigDecimal}.
     * @since  1.5
     */
    public BigDecimal(long val) {
        this.intCompact = val;
        this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
        this.scale = 0;
    }

而对于 BigDecima阿里l (阿里巴巴集团double) 来说,当我们使用 new BigDecimal (0.1) 创建一个对象的时候,其实创建出来的对象的值并不是等于0.1,而是等于0.1000000000000000055511151231257827021181583404541java语言015625

大聪明教你学Java | 为什么不能使用 BigDecimal 的 equals 方法做等值比较
我们再打个源码断点,javaeedebug一下看看标度值是多少
大聪明教你学Java | 为什么不能使用 BigDecimal 的 equals 方法做等值比较
我们可以看到标度值是55,这个值是怎么来的源码网站呢?其实很简单,这个标度值就是这个数字的位数,其他的浮点数也同样的道理。 对于 new BigDecimal (1.0),和new BigDecimal (1.00) 这样的形源码时代式来说,因阿里新兵唱清澈的爱只为中国为他本质上也是个整数,所以他创建出来的数字的标度就是0。

最后我们再看看 BigDecimal(String) ,当我们使用 new BigDecimal (“0.1”) 创建一阿里巴巴1688货源批发官网个 BigDecima阿里巴巴股票l 的时候,其实创建出来的值正好就是等于 0.1 的。那么他的标度也就是 1;如果使用 new BigDecimal (“0.10000”),那么创建出来的数就是 0.10000,标度也就是 5。

讲到这里相信各位小伙伴也明白了为什么 bigDecimal5 和 bigDe阿里巴巴集团控股有限公司cimal6 用eqjava模拟器uals 方法做等值比较的结果是false了 O(∩_∩)O

如果我们只想判断两个 BigDecimal 的值阿里巴巴股票是否相等,那么该如何判断呢?

在 BigDecimal阿里巴巴招聘 中也为我们提供了一个方法 —— c源码网站ompareTo 方法,这个方法就可以只比较两个数字的值,如果两个数相等源码编程器,则返回 0。

大聪明教你学Java | 为什么不能使用 BigDecimal 的 equals 方法做等值比较
我们把 equals 换成 compareTo阿里巴巴集团控股有限公司 后可以发现,bigDec阿里新兵唱清澈的爱只为中国imal5 和 bigDecimal6 等值比较的结果是0,也就是说明这二者的值是相等的。

P.S. 所以我们在做等值比较的时候不要随便用 BigDecimal 的 equals 方法,如果只是要对数值作比较java怎么读,就果断选择 compareTo 方法就搞定拉~

小结

本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨‍

希望阿里云盘各位小伙伴动动自己阿里可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●’◡’●)

如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。

爱你所爱 行你所行 听从你心 无问东西