Actually, I've found possible solution
//returns true
new BigDecimal("5.50").doubleValue() == new BigDecimal("5.5").doubleValue()
Of course, it can be improved with something like Math.abs (v1 - v2) < EPS
to make the comparison more robust, but the question is whether this t开发者_如何转开发echnique acceptable or is there a better solution?
If someone knows why java designers decided to implement BigDecimal's equals in that way, it would be interesting to read.
From the javadoc of BigDecimal
equals
public boolean equals(Object x)
Compares this
BigDecimal
with the specifiedObject
for equality. UnlikecompareTo
, this method considers twoBigDecimal
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).
Simply use compareTo() == 0
The simplest expression to compare ignoring trailing zeros is since Java 1.5:
bd1.stripTrailingZeros().equals(bd2.stripTrailingZeros())
Using ==
to compare doubles seems like a bad idea in general.
You could call setScale to the same thing on the numbers you're comparing:
new BigDecimal ("5.50").setScale(2).equals(new BigDecimal("5.5").setScale (2))
where you would be setting the scale to the larger of the two:
BigDecimal a1 = new BigDecimal("5.051");
BigDecimal b1 = new BigDecimal("5.05");
// wow, this is awkward in Java
int maxScale = Collections.max(new ArrayList() {{ a1.scale(), b1.scale()}});
System.out.println(
a1.setScale(maxScale).equals(b1.setScale(maxScale))
? "are equal"
: "are different" );
Using compareTo() == 0
is the best answer, though. The increasing of the scale of one of the numbers in my approach above is likely the "unnecessary inflation" that the compareMagnitude method documentation is mentioning when it says:
/**
* Version of compareTo that ignores sign.
*/
private int compareMagnitude(BigDecimal val) {
// Match scales, avoid unnecessary inflation
long ys = val.intCompact;
long xs = this.intCompact;
and of course compareTo
is a lot easier to use since it's already implemented for you.
精彩评论