我坚持试图找出为什么这两个操作返回不同的值:
-
Double.NaN == Double.NaN
返回false
-
Double.NaN.Equals(Double.NaN)
返回true
我有答案的第一部分,但不是第二,而不是“为什么这两个比较返回不同的值”
我坚持试图找出为什么这两个操作返回不同的值:
Double.NaN == Double.NaN
返回false
Double.NaN.Equals(Double.NaN)
返回true
我有答案的第一部分,但不是第二,而不是“为什么这两个比较返回不同的值”
究其原因,区别很简单,如果不是很明显。
如果您使用等于运算符==
,那么您使用的是平等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()
方法广泛,并依靠自己的行为的保证。
在注释部分的最底部Double.Equals
,你会发现:
如果两个Double.NaN值通过调用Equals方法相等测试,该方法返回true。 但是,如果两个NaN值是通过使用等号操作符平等测试,操作员返回false。 当您要确定双的值是否不是数字(NAN),另一种是调用IsNaN方法。
那么, 俄德的答案是伟大的,但我想说的东西;
当我反编译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
。
如果您检查Double.NaN;
// Summary:
// Represents a value that is not a number (NaN). This field is constant.
public const double NaN = 0.0 / 0.0;
如NaN被不表示任何数目的第一个返回false。
的方法或操作员返回NaN时的操作的结果是不确定的。 例如,零被零除的结果为NaN
作为第二个返回true NaN
平等在重载显式实现equals
方法。
从MSDN double.equals :
如果两个Double.NaN值通过调用Equals方法相等测试,该方法返回true。 但是,如果两个NaN值是通过使用等号操作符平等测试,操作员返回false。 当您要确定双的值是否不是数字(NAN),另一种是调用IsNaN方法。
这是delibaretly做与符合IEC 60559:1989
;
根据IEC 60559:1989,与南的值的两个浮点数是从来没有equal.However,根据规范的System.Object的:: equals方法,它需要覆盖此方法以提供价值相等的语义。 由于System.ValueType提供通过使用反射此功能,为的Object.Equals中具体说,值类型应考虑重写默认值类型的实现来获得的性能提升。 其实从看System.ValueType源::等于(行36 CLR的\ src \ BCL \ SYSTEM \ ValueType.cs在SSCLI),甚至还有从CLR逆足队System.ValueType的效果评论::等于不为快。
参考: http://blogs.msdn.com/b/shawnfa/archive/2004/07/19/187792.aspx