1. Overview
1.概述
When we want to do decimal number calculations in Java, we may consider using the BigDecimal class.
当我们想在Java中进行十进制数的计算时,我们可以考虑使用BigDecimal类。
In this short tutorial, we’ll explore how to check if a BigDecimal object’s value is zero.
在这个简短的教程中,我们将探讨如何检查一个BigDecimal对象的值是否为零。
2. Introduction to the Problem
2.对问题的介绍
The problem is actually pretty straightforward. Let’s say we have a not-null BigDecimal object. We want to know whether its value is equal to zero.
这个问题其实是很直接的。假设我们有一个非空的BigDecimal对象。我们想知道它的值是否等于零。
Sharp eyes may have already realized that the requirement “whether its value is equal to zero” has implied the solution: using the equals() method. Further, the BigDecimal class provides a convenient ZERO constant object to indicate the zero value.
敏锐的眼睛可能已经意识到,”是否其值等于零“的要求已经暗示了解决方案:使用equals()方法。此外,BigDecimal类提供了一个方便的ZERO常量对象来表示零值。
Indeed, this problem sounds pretty simple. We could simply check BigDecimal.ZERO.equals(givenBdNumber) to decide if the givenBdNumber object has the value zero. However, if we don’t know BigDeicmal‘s comparison intricacies, we may fall into a common pitfall.
的确,这个问题听起来很简单。我们可以简单地检查BigDecimal.ZERO.equals(givenBdNumber)来决定givenBdNumber对象的值是否为0。然而,如果我们不了解BigDeicmal的比较的复杂性,我们可能会掉进一个常见的陷阱。
Next, let’s take a closer look at it and address the proper ways to solve it.
接下来,让我们仔细看看,并解决解决它的正确方法。
3. The Common Pitfall of BigDecimal Comparison: Using the equals Method
3.BigDecimal比较的常见陷阱 使用equals方法
First, let’s create a BigDecimal object with zero as the value:
首先,让我们创建一个BigDecimal对象,值为0。
BigDecimal BD1 = new BigDecimal("0");
Now, let’s check if BD1‘s value is zero using the equals method. For simplicity, let’s do this in a unit test method:
现在,让我们使用BD1方法检查equals的值是否为零。为了简单起见,让我们在一个单元测试方法中做这个。
assertThat(BigDecimal.ZERO.equals(BD1)).isTrue();
If we run the test, it’ll pass. So far, so good. We may think it’s the solution. Next, let’s create another BigDecimal object:
如果我们运行测试,它将通过。到目前为止,一切都很好。我们可能认为这就是解决方案。接下来,让我们再创建一个BigDecimal对象。
BigDecimal BD2 = new BigDecimal("0.0000");
Apparently, the BD2 object’s value is zero, although we’ve constructed it by a string with a scale of four. As we all know, 0.0000 is the same as 0 in value.
显然,BD2对象的值是0,尽管我们用一个比例为4的字符串来构建它。我们都知道,0.0000在数值上与0相同。
Now, let’s test BD2 with the equals method again:
现在,让我们再次用equals方法测试BD2。
assertThat(BigDecimal.ZERO.equals(BD2)).isTrue();
This time, if we run the method, surprisingly, the test will fail.
这一次,如果我们运行这个方法,令人惊讶的是,测试将失败。
This is because a BigDecimal object has value and scale attributes. Moreover, the equals method considers two BigDecimal objects equal only if they are equal in both value and scale. That is to say, BigDecimal 42 is not equal to 42.0 if we compare them with equals.
这是因为BigDecimal对象有值和比例属性。此外,equals方法认为两个BigDecimal对象只有在值和比例都相等时才是相等的。也就是说,如果我们用equals来比较,BigDecimal 42不等于42.0。
On the other side, the BigDecimal.ZERO constant has the value zero and a scale of zero, too. So, when we check “0 equals 0.0000“, the equals method returns false.
另一方面,BigDecimal.ZERO常数的值为0,刻度也为0。因此,当我们检查”0等于0.0000“时,equals方法返回false。
Therefore, we need to find a way only to compare two BigDecimal objects’ values but ignore their scales.
因此,我们需要找到一种方法,只比较两个BigDecimal对象的值,但忽略它们的尺度。
Next, let’s see a couple of approaches to solve the problem.
接下来,让我们看看解决这个问题的几个方法。
4. Using the compareTo Method
4.使用compareTo方法
The BigDecimal class implements the Comparable interface. So, we can use the compareTo method to compare two BigDecimal objects’ values.
BigDecimal类实现了Comparable接口。因此,我们可以使用compareTo方法来比较两个BigDecimal对象的值。
Further, the compareTo method’s Javadoc clearly states:
此外,compareTo方法的Javadoc明确指出。
Two BigDecimal objects that are equal in value but have a different scale (like 2.0 and 2.00) are considered equal by this method.
两个BigDecimal对象的值相等,但比例不同(如2.0和2.00),在此方法中被视为相等。
Therefore, we can check BigDecimal.ZERO.compareTo(givenBdNumber) == 0 to decide if givenBdNumber has the value zero.
因此,我们可以检查BigDecimal.ZERO.compareTo(givenBdNumber) == 0来决定givenBdNumber的值是否为0。
Next, let’s test if this method can correctly tell if both BigDecimal objects BD1 and BD2 are zero:
接下来,让我们测试一下这个方法是否能正确判断BigDecimal对象BD1和BD2是否都是零。
assertThat(BigDecimal.ZERO.compareTo(BD1)).isSameAs(0);
assertThat(BigDecimal.ZERO.compareTo(BD2)).isSameAs(0);
When we run the test, it passes. So, we’ve solved the problem using the compareTo method.
当我们运行测试时,它通过了。所以,我们已经用compareTo方法解决了这个问题。
5. Using the signum Method
5.使用signum方法
The BigDeicmal class provides the signum method to tell if the given BigDecimal object’s value is negative (-1), zero (0), or positive (1). The signum method will ignore the scale attribute.
BigDeicmal类提供了signum方法来告诉给定的BigDecimal对象的值是负数(-1)、零(0)还是正数(1)。signum方法将忽略刻度属性。
Therefore, we can solve the problem by checking (givenBdNumber.signum() == 0).
因此,我们可以通过检查(givenBdNumber.signum() == 0)/em>来解决问题。
Again, let’s write a test to verify if this approach works for the two examples:
同样,让我们写一个测试来验证这种方法对这两个例子是否有效。
assertThat(BD1.signum()).isSameAs(0);
assertThat(BD2.signum()).isSameAs(0);
The test above passes if we give it a run.
如果我们让它运行一下,上面的测试就会通过。
6. Conclusion
6.结语
In this short article, we’ve addressed two proper ways to check if a BigDecimal object’s value is zero: the compareTo method or the signum method.
在这篇短文中,我们讨论了两种检查BigDecimal对象的值是否为零的正确方法:compareTo方法或signum方法。
As usual, the complete code of this article can be found over on GitHub.
像往常一样,本文的完整代码可以在GitHub上找到over。