Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Why prohibit the use of BigDecimal's equals method for equivalent comparison

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

In this article Xiaobian for you to introduce in detail "why it is forbidden to use BigDecimal's equals method to do equivalence comparison", the content is detailed, the steps are clear, and the details are handled properly. I hope that this article "Why it is forbidden to use BigDecimal's equals method to do equivalence comparison" can help you solve your doubts.

BigDecimal many people should have heard of it and know its usage. It is a type provided in the java.math package that can be used to perform precise operations.

As many people know, in scenarios such as amount representation, amount calculation, and so on, you can't use double, float and other types, but rather use a better BigDecimal that supports precision.

Therefore, in many payment, e-commerce, financial and other businesses, BigDecimal is used very frequently. And I have to say that this is a very easy-to-use class, which has many internal methods, such as addition, subtraction, multiplication, division and other operations can be called directly.

In addition to the need to use BigDecimal to represent numbers and perform number operations, there is often a need to judge the equality of numbers in code.

So, why is there such a requirement? What is the thinking behind it?

In fact, I have seen the following low-level errors in the previous CodeReview:

If (bigDecimal = = bigDecimal1) {/ / two equal numbers}

This kind of error, I believe that smart readers can see the problem at a glance, because BigDecimal is an object, so you can not use = = to determine whether the values of two numbers are equal.

The above problems can be avoided after some experience, but smart readers, take a look at the following line of code, do you think he has a problem:

If (bigDecimal.equals (bigDecimal1)) {/ / two numbers are equal}

I can tell you clearly that the result of the above writing may be different from what you expected!

Let's do an experiment and 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))

The output of the above code is as follows:

The equals principle of truetruefalseBigDecimal

From the above code example, we find that when comparing 1 and 1.0 using BigDecimal's equals method, sometimes it is true (when using int, double to define BigDecimal), sometimes it is false (when String is used to define BigDecimal).

So why is this happening? let's take a look at BigDecimal's equals method first.

The reason has already been explained in BigDecimal's JavaDoc:

Compares this BigDecimal with the specified Object for equality. Unlike compareTo, this method considers two 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)

The general meaning is that the equals method is not the same as compareTo. The equals method compares two parts, namely, value and scale.

Therefore, the precision of the two BigDecimal objects (bigDecimal4 and bigDecimal5) defined by our above code is not the same, so the result of equals comparison is false.

Try to debug the code, in the process of debug, we can also see that the precision of bigDecimal4 is 0, while the precision of bigDecimal5 is 1.

At this point, we have probably explained that the reason why equals compares bigDecimal4 and bigDecimal5 is false because of the difference in precision.

So why is the accuracy different? Why is it that bigDecimal2 and bigDecimal3 have the same precision (when using int and double to define BigDecimal), while bigDecimal4 and bigDecimal5 are different (when using String to define BigDecimal)?

Why is the precision different?

This is related to the accuracy of BigDecimal, this problem is actually quite complex, because it is not the focus of this article, here is a brief introduction. If you are interested, we will talk about it separately later.

First of all, BigDecimal has the following four construction methods:

BigDecimal (int)

BigDecimal (double)

BigDecimal (long)

BigDecimal (String)

The precision of the BigDecimal created by the above four methods is different.

BigDecimal (long) and BigDecimal (int)

First of all, the simplest ones are BigDecimal (long) and BigDecimal (int). Because they are integers, the precision is 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;} 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, but 0.10000000000000055511151231257827021181583404541015625. This is because doule itself represents only an approximate value.

So, whether we use the definition of new BigDecimal (0.1) or new BigDecimal (0.10), his approximate value is 0.1000000000000005551115123125782702118158404541015625, then his precision is the number of digits of this number, that is, 55.

The same is true of other floating point numbers. For a form like new BigDecimal, because it is also an integer in nature, the precision of the number he created is 0.

So, because the precision of BigDecimal (1. 0) is the same as that of BigDecimal (1. 00), the result is true when comparing with equals method.

BigDecimal (string)

For BigDecimal (double), when we use new BigDecimal ("0.1") to create a BigDecimal, the value created is exactly equal to 0.1. Then his accuracy is 1.

If you use new BigDecimal ("0.10000"), the number created is 0.10000, and the precision is 5.

So, because the precision of BigDecimal ("1. 0") is not the same as that of BigDecimal ("1. 00"), when comparing with the equals method, the result is false.

How to compare BigDecimal

Earlier, we explained that BigDecimal's equals method actually compares not only the values of numbers, but also their accuracy.

Therefore, when we use the equals method to judge whether two numbers are equal, it is extremely strict.

So, if we just want to determine whether the values of two BigDecimal are equal, how do we do that?

The compareTo method is provided in BigDecimal, which compares only the values of two numbers and returns 0 if the two numbers are equal.

BigDecimal bigDecimal4 = new BigDecimal ("1"); BigDecimal bigDecimal5 = new BigDecimal ("1.0000"); System.out.println (bigDecimal4.compareTo (bigDecimal5))

The above code, output the result:

0 read here, this article "Why to prohibit the use of BigDecimal's equals method to do equivalent comparison" article has been introduced, want to master the knowledge of this article still need to practice and use in order to understand, if you want to know more related articles, welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report