2014-05-02 52 views
9

我正在寫一個類Vec2D,表示一個2維向量。我在double中儲存了xyDouble.doubleToLongBits(x)的含義

當記者問到產生equals(Object objhashCode(),日食產生這樣的:

@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    long temp; 
    temp = Double.doubleToLongBits(x); 
    result = prime * result + (int) (temp^(temp >>> 32)); 
    temp = Double.doubleToLongBits(y); 
    result = prime * result + (int) (temp^(temp >>> 32)); 
    return result; 
} 
@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    Vec2D other = (Vec2D) obj; 
    if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x)) 
     return false; 
    if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y)) 
     return false; 
    return true; 
} 

什麼是Double.doubleToLongBits(x)在這方面的意義是什麼?我能不能簡單地寫x != other.x

回答

9

簡短的回答:Eclipse使用Double.doubleToLongBits因爲這是Double.equals做:

結果是true當且僅當參數不是null,是一個Double對象,它表示一個doublË具有與由此對象表示的double相同的值。爲此目的,當且僅當方法doubleToLongBits(double)在應用於每個值時返回相同的long值時,兩個double值被視爲相同。

長答案:JLS指定了Double.equals和==之間的一些區別。對於JLS 4.2.3JLS 15.21.1中指定的一個區別:

正零和負零比較相等;因此表達式0.0==-0.0的結果是true並且0.0>-0.0的結果是false。但其他操作可以區分正數和負數;例如,1.0/0.0的值爲正無窮大,而1.0/-0.0的值爲負無窮大。

另一個方面NaN

如果操作數爲NaN,則==結果是false!=結果是true

確實,測試x!=xtrue當且僅當x的值是NaN。

正如你所看到的,有可能爲兩個雙值與==比較,但在數學和哈希表使用時,實際上對應於不同的行爲。因此,在編寫一個生成的平等方法時,Eclipse假設兩個雙打只有當它們可以完成的所有操作相同時(或等價地)如果它們被自動裝箱並與它們的方法進行比較,它們之間的關係纔是相等的。如果在doubleDouble之間切換,這一點尤爲重要 - 對於平等屬性的差異,這一點尤其出乎意料。

當然,你可以自由地擺脫這個假設:無論是否是一個好主意,你可以爲許多可能的NaN表示中的任何一個分配特殊情況,在這種情況下Double.doubleToRawLongBits()會更適合你equalshashCode方法。同樣,您的用例可能會將+0.0和-0.0的對象視爲等效對象,並保證不可能使用NaN值,在這種情況下,原始==比較可能對equals效果更好(但在此時模擬相同的標準hashCode變得困難)。

0

在網上的javadoc收率此快速瀏覽:

返回根據IEEE 754浮點「雙精度格式」位佈局一個指定的浮點值的表示。

...

在所有情況下,結果是一個長整數,當給予longBitsToDouble(長)的方法,將產生一個浮點值一樣與doubleToLongBits的參數(除所有NaN值被摺疊爲一個「規範」NaN值)。

因此它可能是標準化的xydouble表示的方式,因爲NaN的可以有多個double表示

3

因爲==!=遵循IEEE-754語義雙打,Double.NaN != Double.NaN0.0 == -0.0。這些行爲可能不是您想要的,所以Double.doubleToLongBits()double數據的64位轉換爲64位的long數據,以便像位移和異或操作一樣工作。

老實說,雖然,我要說的是,使用doubleToLongBits是一個bug在這裏,如果你關心確切的平等,因爲你應該使用Double.doubleToRawLongBits()(這完全不執行的double數據的任何翻譯)來代替。

相關問題