BigDecimal比較大小注意事項(equals)
阿新 • • 發佈:2019-01-04
在專案中使用BigDecimal的equals方法比較大小時,結果不為true,直接上示例
public static void main(String[] args) { BigDecimal a = new BigDecimal(0.00); BigDecimal b = new BigDecimal(0); boolean result = a.equals(b); System.out.println("a equals b -->" + result); BigDecimal c = new BigDecimal("0.00"); BigDecimal d = new BigDecimal("0"); boolean result1 = c.equals(d); System.out.println("c equals d -->" + result1); }
結果:
a equals b -->true
c equals d -->false
可以看到a和b比較結果是true,c和d比較的結果為fasle
c、d使用傳入字串的構造器(等同於資料庫查詢出來的值)
專案中從資料庫查詢出來的值進行比較時(上例中c、d)顯然不是我們期望的結果,因此修改為如下方法
boolean result2 = c.compareTo(d) == 0;
System.out.println("c compareTo d -->" + result2);
結果:
c compareTo d -->true
我們來看下構造器:
public BigDecimal(String val) { this(val.toCharArray(), 0, val.length()); }
該構造器的註釋:
可以看出,“0”傳入構造器得到的是0且沒有小數位,“0.00”傳入構造器得到的是0.00,含有2位小數
再看看equals方法:
@Override public boolean equals(Object x) { if (!(x instanceof 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()); }
可以清晰看到equals方法比較了小數位數 -----> if (scale != xDec.scale) return false;
到這裡可以理解上面C、Dequals比較結果為什麼是false了
再來看看compareTo方法
/**
* Compares this {@code BigDecimal} with the specified
* {@code BigDecimal}. Two {@code BigDecimal} objects that are
* equal in value but have a different scale (like 2.0 and 2.00)
* are considered equal by this method. This method is provided
* in preference to individual methods for each of the six boolean
* comparison operators ({@literal <}, ==,
* {@literal >}, {@literal >=}, !=, {@literal <=}). The
* suggested idiom for performing these comparisons is:
* {@code (x.compareTo(y)} <<i>op</i>> {@code 0)}, where
* <<i>op</i>> is one of the six comparison operators.
*
* @param val {@code BigDecimal} to which this {@code BigDecimal} is
* to be compared.
* @return -1, 0, or 1 as this {@code BigDecimal} is numerically
* less than, equal to, or greater than {@code val}.
*/
public int compareTo(BigDecimal val) {
// Quick path for equal scale and non-inflated case.
if (scale == val.scale) {
long xs = intCompact;
long ys = val.intCompact;
if (xs != INFLATED && ys != INFLATED)
return xs != ys ? ((xs > ys) ? 1 : -1) : 0;
}
int xsign = this.signum();
int ysign = val.signum();
if (xsign != ysign)
return (xsign > ysign) ? 1 : -1;
if (xsign == 0)
return 0;
int cmp = compareMagnitude(val);
return (xsign > 0) ? cmp : -cmp;
}
可以看到,分了2種情況,一種是含有小數位相同,另一種時不相同的情況。所以不管2個數的小數位是否相同,都會進行值的比較。