BigDecimal, which will be familiar to many of you and will be familiar with its use, is a type provided in the Java.Math package that can be used to perform precise calculations.
Many of you know that you should not use double, float, etc., but rather use BigDecimal, which has better precision support, when doing amount representation, amount calculation, etc.
As a result, BigDecimal is used frequently in many payment, e-commerce, and finance businesses. And have to say that this is a very good class, its internal with 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.
About this knowledge point, in the latest version of the “Alibaba Java Development Manual” also has the explanation:
What’s the thinking behind this?
In the previous CodeReview, I saw the following silly errors:
If (bigDecimal == bigDecimal1){// Two numbers equal}Copy the code
This error will be obvious to an intelligent reader, since BigDecimal is an object and cannot be used to determine whether two numbers are equal or not.
With some experience, the above problem can be avoided, but intelligent readers, take a look at the following line of code, do you think it has a problem:
If (bigdecimal. equals(bigDecimal1)){// Two numbers equal}Copy the code
We can clearly tell you that the above writing method, may get the results and you expect different!
To do an experiment, run the following code:
BigDecimal bigDecimal = new BigDecimal(1);
BigDecimal bigDecimal1 = new BigDecimal(1);
System.out.println(bigDecimal.equals(bigDecimal1));
BigDecimal bigDecimal2 = new BigDecimal(1);
BigDecimal bigDecimal3 = new BigDecimal(1.0);
System.out.println(bigDecimal2.equals(bigDecimal3));
BigDecimal bigDecimal4 = new BigDecimal("1");
BigDecimal bigDecimal5 = new BigDecimal("1.0");
System.out.println(bigDecimal4.equals(bigDecimal5));
Copy the code
In the above code, the output is:
true
true
false
Copy the code
Equals principle for BigDecimal
From the code example above, we saw that when comparing 1 to 1.0 using BigDecimal’s equals method, it is sometimes true (when defining BigDecimal using int, double), Sometimes false (when BigDecimal is defined with String).
So, why does this happen? Let’s look at BigDecimal’s equals method first.
The reason for this is explained in BigDecimal’s JavaDoc:
Compares this BigDecimal with the specified Object for equality. Unlike compareTo, This method fails to provide a foundation for managerial positions this method fails to provide a foundation for managerial positions this method fails to provide a foundation for managerial positions this method fails to provide a foundation for managerial positions this method fails to provide a foundation for managerial positions 2.00 When compared by this method)Copy the code
Unlike compareTo, equals compares two things: value and scale.
The corresponding code is as follows:
Therefore, the two BigDecimal objects defined by our code above (bigDecimal4 and bigDecimal5) are of different precision, so using equals comparison results in false.
Trying to debug the code, we can also see that bigDecimal4 has an accuracy of 0 while bigDecimal5 has an accuracy of 1.
At this point, we’ve probably explained that equals compares bigDecimal4 and bigDecimal5 with false because of the difference in accuracy.
So why the difference in accuracy? Why are bigDecimal2 and bigDecimal3 exactly the same (when BigDecimal is defined with int, double), but bigDecimal4 and bigDecimal5 not the same (when BigDecimal is defined with String)?
Why the accuracy is different
This is where the precision of BigDecimal comes in, which is a bit more complicated and is not the focus of this article, so I’ll cover it briefly here. If you’re interested, we’ll talk about it separately.
First, There are four constructors for BigDecimal:
BigDecimal(int)
BigDecimal(double)
BigDecimal(long)
BigDecimal(String)
Copy the code
The accuracy of the BigDecimal created by these four methods is different.
BigDecimal (long) and BigDecimal (int)
First, the simplest ones are BigDecimal(long) and BigDecimal(int), which, since they are integers, have precision 0:
public BigDecimal(int val) {
this.intCompact = val;
this.scale = 0;
this.intVal = null;
}
public BigDecimal(long val) {
this.intCompact = val;
this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
this.scale = 0;
}
Copy the code
BigDecimal(double)
For BigDecimal(double), when we create a BigDecimal using new BigDecimal(0.1), the value created is not exactly equal to 0.1, Instead of 0.1000000000000000055511151231257827021181583404541015625. This is because doule itself represents only an approximation.
So, whether we use the new BigDecimal (0.1) or a new BigDecimal (0.10) definition, he approximation is 0.1000000000000000055511151231257827021181583404541015625 this, So his accuracy is the number of bits of this number, which is 55.
The same is true for other floating-point numbers. For a form like New BigDecimal(1.0), which is essentially an integer, the precision of the number created is 0.
So, because BigDecimal(1.0) and BigDecimal(1.00) have the same precision, the result is true when comparing using equals.
BigDecimal(string)
For BigDecimal(double), when we create a BigDecimal using new BigDecimal(“0.1”), the value created is exactly equal to 0.1. So his accuracy is going to be 1.
If you use New BigDecimal(“0.10000”), the number created is 0.10000, with an accuracy of 5.
Therefore, because BigDecimal(“1.0”) and BigDecimal(“1.00”) have different precision, the result is false when comparing using equals.
How do YOU compare BigDecimal
Earlier, we explained that BigDecimal’s Equals method not only compares the values of numbers, but also their precision.
So when we use the equals method to determine whether two numbers are equal, we are extremely strict.
So, what if we just want to determine whether two BigDecimal values are equal?
The compareTo method is provided in BigDecimal, which can compare the values of only two numbers and return 0 if they are equal.
BigDecimal bigDecimal4 = new BigDecimal("1");
BigDecimal bigDecimal5 = new BigDecimal("1.0000");
System.out.println(bigDecimal4.compareTo(bigDecimal5));
Copy the code
Above code, output result:
0
Copy the code
The source code is as follows:
conclusion
BigDecimal is a very useful class for representing high-precision numbers, with many rich methods.
Equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals
If readers want to compare the values of two BigDecimal, they can use the compareTo method.
Concern public number: programmer interview scene. Reply “Manual” to obtain the latest version of the manual.