我被困試圖找出爲什麼這兩個操作返回不同的值:Double.NaN與自身比較
Double.NaN == Double.NaN
返回false
Double.NaN.Equals(Double.NaN)
返回true
我有answer到第一部分但不是第二部分,而不是「爲什麼這兩個比較返回不同的值」
我被困試圖找出爲什麼這兩個操作返回不同的值:Double.NaN與自身比較
Double.NaN == Double.NaN
返回false
Double.NaN.Equals(Double.NaN)
返回true
我有answer到第一部分但不是第二部分,而不是「爲什麼這兩個比較返回不同的值」
如果不明顯,差異的原因很簡單。
如果您使用相等運算符==
,那麼您使用的是IEEE測試的相等性。
如果您使用的是Equals(object)
方法,那麼您必須維護object.Equals(object)
的合同。實施此方法(和相應的GetHashCode
方法)時,您必須維護該合同,這與IEEE行爲不同。
如果Equals
合同沒有被維護,那麼哈希表的行爲就會中斷。
var map = new Dictionary<double,string>();
map[double.NaN] = "NaN";
var s = map[double.NaN];
如果!double.NaN.Equals(double.NaN)
,你永遠不會從字典中得到你的價值!
如果前面一句沒有意義,那麼理解散列的機制(在Dictionary<T,U>
,HashSet<T>
等使用)同時使用object.Equals(object)
和object.GetHashCode()
方法廣泛,並且依靠自己的行爲的保證。
啊。最後。 :-)(我非常希望在這裏爲索賠找到適當的參考,但我相信這是正確的答案(合同部分肯定是),所以+1)。 –
是的,我應該指出,我沒有參考。這只是對我有意義的唯一原因。 –
+1。你能否提供一個參考IEEE測試平等的參考?我找不到它的任何地方 – GETah
如果您檢查Double.NaN;
// Summary:
// Represents a value that is not a number (NaN). This field is constant.
public const double NaN = 0.0/0.0;
第一個返回false,因爲NaN不代表任何數字。
方法或操作符返回NaN當操作的結果是 未定義。例如,零被零除的結果是NaN
如NaN
平等在重載equals
方法明確地實現第二個返回true。
如果兩個Double.NaN值通過調用的Equals 方法的相等測試,該方法返回true。但是,如果使用相等運算符對兩個NaN值進行 的相等性檢驗,則運算符返回 false。當你想確定Double的值是不是 的數字(NaN)時,另一種方法是調用IsNaN方法。
這是完成delibaretly以符合IEC 60559:1989
;
根據IEC 60559:1989,與 的NaN的值的兩個浮點數是從未equal.However,根據本說明書的System.Object的:: Equals已 方法,這是期望的是覆蓋此方法以提供值爲 的平等語義。由於System.ValueType通過使用Reflection來提供此功能,因此Object.Equals的說明特別指出,值類型應該考慮 覆蓋默認的ValueType實現以獲得增加的性能 。事實上,通過查看 System.ValueType :: Equals(clr \ src \ BCL \ System \ ValueType的第36行)的來源。cs 在SSCLI中),甚至有來自CLR Perf團隊的評論意見,因爲System.ValueType :: Equals不是很快的 效應。
參考:http://blogs.msdn.com/b/shawnfa/archive/2004/07/19/187792.aspx
問題是**爲什麼**這兩種方法產生不同的結果。你沒有回答。 –
我確實相信我已經回答了; NaN沒有定義,不代表任何數字,它是未定義的。談論平等是不可能的;但equals方法定義了兩個NaN值之間的等式。 – daryal
*爲什麼*是這樣定義的'Equals'?你只是[乞求問題](https://en.wikipedia.org/wiki/Begging_the_question)。 –
好,Oded's answer是偉大的,但我想說的東西;
當我反編譯Double.Equals()
方法時,看起來像這樣;
public bool Equals(double obj)
{
return ((obj == this) || (IsNaN(obj) && IsNaN(this)));
}
所以,因爲我們有這個= Double.NaN和的obj = Double.NaN
(IsNaN(obj)) and (IsNaN(this)) returns `true`.
所以basicly很可能return ((obj == this) || true
這等同放着清單
return ((obj == this)
是true
。
+1。我現在越來越困惑:p – GETah
而且這只是乞討的問題。我們已經知道* Double.Equals對NaN有特殊的處理,問題是* why。 –
@KonradRudolph,我解釋了爲什麼在我的答案。這是因爲必須維護語義合約。 –
可能是一個愚蠢的評論,但我會說,情況1,你是比較值。在案例2中,您正在比較參考。 – jbl
@jbl不,你在比較兩種情況下的值 - 'double's不是引用,因爲['System.Double.Equals'](http://msdn.microsoft.com/ en-us/library/ya2zha7s.aspx)被重載。 –
@spender OMFG我應該更好地閱讀這個問題!謝謝! –