2015-05-07 18 views
2

Java的方式來比較兩個BigDecimals的是使用的compareTo()方法,並檢查結果爲-1,0或1。在groovy/grails中使用BigDecimal的比較運算符是否安全?

BigDecimal a = new BigDecimal("1.23") 
BigDecimal b = new BigDecimal("3.45") 
if (a.compareTo(b) > 0)) { } 

我已經看到了一些人使用的Grails這種格式:

if (a > b) { } 

這是可行的嗎?即它會得到正確的小數,還是它轉換爲浮動或類似的比較?

如何使用「==」與使用equals()?

什麼是像這樣的後果:

BigDecimal a = new BigDecimal("1.00") 
BigDecimal b = new BigDecimal("1") 
assert (a==b) 

看來工作,但我們沒有這麼根深蒂固在Java中不要做這種事情。

+ =?例如

a+=b? 

這會是一樣的

a = a.add(b) 

哪裏找到一個這樣的東西出來?我有兩本groovy書籍,不幸的是既沒有提到BigDecimal比較或算術,也沒有提到轉換/聲明。

+0

答案是肯定的,在Groovy/grails的BigDecimals上使用比較(和關節)操作符是安全的,完整列表在這裏:http://www.ibm.com/developerworks/library/j-pg10255 /感謝mohsenmadi和Nathan Hughes –

回答

1

Groovy允許運算符重載。當一個類型實現某些方法時,您可以使用該類型的相應運算符。

對於+實施的方法是加號,而不是加號。

對於大於或小於比較,Groovy在該對象上查找compareTo方法,併爲==查找名爲equals的方法。 (如果你想比較引用彷彿在Java中使用==,你必須使用is

下面是常見的數學運算符的表和方法用於重載它們:

Operator  Method 
a + b  a.plus(b) 
a - b  a.minus(b) 
a * b  a.multiply(b) 
a/b  a.divide(b) 
a++ or ++a a.next() 
a-- or --a a.previous() 
a << b  a.leftShift(b) 

你可以看到該BigDecimal的重載一些方法(你操作符重載的加,減,乘,除,而不是下一個,上一個,或leftShift):

groovy:000> BigDecimal.methods*.name 
===> [equals, hashCode, toString, intValue, longValue, floatValue, doubleValue, 
byteValue, shortValue, add, add, subtract, subtract, multiply, multiply, divide, 
divide, divide, divide, divide, divide, remainder, remainder, divideAndRemainde 
r, divideAndRemainder, divideToIntegralValue, divideToIntegralValue, abs, abs, m 
ax, min, negate, negate, plus, plus, byteValueExact, shortValueExact, intValueEx 
act, longValueExact, toBigIntegerExact, toBigInteger, compareTo, precision, scal 
e, signum, ulp, unscaledValue, pow, pow, movePointLeft, movePointRight, scaleByP 
owerOfTen, setScale, setScale, setScale, stripTrailingZeros, toEngineeringString 
, toPlainString, round, compareTo, getClass, notify, notifyAll, wait, wait, wait 
, valueOf, valueOf, valueOf] 

所以操作者造成方法的BigDecimal宣佈已經,或通過groovy添加到BigDecimal,以獲得調用。它絕對不會對像float這樣的基本類型進行任何類型的轉換,以便能夠在基元上使用運算符。

該表取自this developerworks article by Andrew Glover and Scott Davis,其中有更多的細節和示例代碼。

+0

啊哈!您找到的鏈接可以解答所有問題。我很努力,但沒有找到這個寶石。 –

0

Groovy在數字管理和無限精度方面做得非常出色。首先你應該知道的是,任何有一個點的數字默認都是一個BigDecimal - 無限精度的原因。這是一個這意味着什麼的例子。請考慮以下代碼片段:

System.out.println(2.0 - 1.1); 
    System.out.println(new BigDecimal(2.0).subtract(new BigDecimal(1.1))); 
    System.out.println(new BigDecimal("2.0").subtract(new BigDecimal("1.1"))); 

    // the above will give these: 
    0.8999999999999999 
    0.899999999999999911182158029987476766109466552734375 
    0.9 

這顯示了我們必須經歷以獲得Java體驗的耐力。在Groovy中,這是你所要做的:

println 2 - 1.1​ 

得到你的0.9!試試Groovy web console。這裏,第二個操作數是一個BigDecimal,所以整個計算都在BigDecimal中,而精確度是Groovy在這種情況下努力完成的。

但是如何?這是因爲在Groovy幾乎每一個操作者被映射到方法在引擎蓋下的對象調用,所以A + Ba.plus(b)中,和一個== b轉換爲a.compareTo(二)。因此,假定你所假設的是安全的,這就是Groovy的做事方式:少寫,明文表達,Groovy會爲你做這項工作。你可以通過例子全部瞭解Groovy-lang documentation page中的所有內容。

+0

非常酷,但我們是否也可以使用a> b而不是a.compareTo(b)> 0? –

+0

確實!就像我說的那樣,少寫點,期待「正確」。例如,>運算符不僅適用於Groovy中的數字,您甚至可以在對象上運行它。試試這個:assert「one」>「two」== false,或者是true。你發現了什麼?即使>運算符超載。 – mohsenmadi

相關問題