preface

BigDecimal is a type provided in the Java.Math package that can be used to perform precise operations. As a result, BigDecimal is frequently used in payment, e-commerce, and other businesses. And its internal has a lot of methods, such as addition, subtraction, multiplication, division and other operations can be directly called. In addition to the need to represent numbers in BigDecimal and perform number operations, equality judgments for numbers are often required in code.

When it comes to equivalent comparison, let’s first look at the requirements in “Alibaba Java Development Manual” πŸ‘‡ :So why would there be such a request πŸ€”~ what is the mystery of πŸ€”~ please listen to my little partners…

BigDecimal does an equivalence comparison

    public static void main(String[] args) {
        BigDecimal bigDecimal1 = new BigDecimal(1);
        BigDecimal bigDecimal2 = new BigDecimal(1);

        if(bigDecimal1 == bigDecimal2){
            // Equivalent comparison}}Copy the code

The above code is problematic because BigDecimal is an object and cannot be used to make equivalence judgments using ==.

What if we use BigDecimal’s equals method to do an equivalence comparison? πŸ‘‡

    public static void main(String[] args) {
        BigDecimal bigDecimal1 = new BigDecimal(1);
        BigDecimal bigDecimal2 = new BigDecimal(1);

        if(bigDecimal1.equals(bigDecimal2)){
            // Equivalent comparison}}Copy the code

In a twist, let’s run the code to see if we can do an equivalent comparison using BigDecimal’s equals method (●’β—‘’●).

    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));

    }
Copy the code

We can see that when comparing 1 and 1.0 using BigDecimal’s equals method: We define BigDecimal as true using int and double; Defining BigDecimal with String results in false. Why is this the case?

Let’s take a look at the equals method source πŸ‘‡

	/**
     * 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(! (xinstanceof 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());
    }
Copy the code

BigDecimal5 and bigDecimal6 have the same value, but not the same scale.

Let’s make a breakpoint and debug to see ~

We can see that the scale value of bigDecimal5 is 0 and the scale value of bigDecimal6 is 1, so the comparison between bigDecimal5 and bigDecimal6 is false (● weighting ●)

Then another question arises: why are the scales different? πŸ€”

Hee hee ~ everyone little friends calm down, please listen to me ~

There are four constructors for BigDecimal:

  • BigDecimal(int)
  • BigDecimal(double)
  • BigDecimal(long)
  • BigDecimal(String)

The easiest to understand are BigDecimal(int) and BigDecimal(long), which are integers and therefore scale to 0 (source: πŸ‘‡) :

	/**
     * 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}.
     * @since1.5 * /
    public BigDecimal(int val) {
        this.intCompact = val;
        this.scale = 0;
        this.intVal = null;
    }
Copy the code
	/**
     * 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}.
     * @since1.5 * /
    public BigDecimal(long val) {
        this.intCompact = val;
        this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
        this.scale = 0;
    }
Copy the code

For BigDecimal (double), when we create an object using new BigDecimal (0.1), the value of the object created is not equal to 0.1, It is equal to 0.1000000000000000055511151231257827021181583404541015625Let’s make another breakpoint and debug to see what the scale value isWe can see that the scale value is 55, where does this value come from? In fact, the scale value is the number of bits of the number, and the same is true for any floating point number. For forms such as New BigDecimal (1.0) and New BigDecimal (1.00), since it is also an integer in nature, the numbers created by it have a scale of 0.

Finally, we look at BigDecimal(String). When we create a BigDecimal using new BigDecimal(“0.1”), the value created is exactly equal to 0.1. So his scale is going to be 1; If you use New BigDecimal (“0.10000”), the number created is 0.10000 and the scale is 5.

BigDecimal5 and bigDecimal6 are false based on their equals method

If we just want to determine whether two BigDecimal values are equal, how do we do that?

We are also provided with a method in BigDecimal, the compareTo method, which can compare only the values of two numbers and return 0 if they are equal.If we change equals to compareTo, we can see that bigDecimal5 and bigDecimal6 are equal to each other.

P.S. So don’t use BigDecimal’s equals method when comparing values. If you just want to compare values, choose compareTo and pull ~

summary

My experience is limited, some places may not be particularly in place, if you think of any questions when reading, welcome to leave a message in the comments section, we will discuss one by one πŸ™‡

Please take a thumbs up and a follow (βœΏβ—‘β€Ώβ—‘) for this article ~ a crab (●’β—‘’●)

If there are mistakes in the article, welcome to comment correction; If you have a better, more unique understanding, you are welcome to leave your valuable ideas in the comments area.

Love what you love, do what you do, listen to your heart and ask nothing