谁可以给我解释一下这个?在C#中,double.NaN不等于double.NaN
bool huh = double.NaN == double.NaN; // huh = false
bool huh2 = double.NaN >= 0; // huh2 = false
bool huh3 = double.NaN <= 0; // huh3 = false
Run Code Online (Sandbox Code Playgroud)
我可以将什么常数与double.NaN相比并得到真实?
这一切都始于一个有趣的问题,有人向我提出.(它在书中提到 - 简而言之C#)下面是它的要点.
Double a = Double.NaN;
Console.WriteLine(a == a); // => false
Console.WriteLine(a.Equals(a)); // => true
Run Code Online (Sandbox Code Playgroud)
以上似乎不对.a应始终为==自身(引用相等)并且两者应该是一致的.
看起来像Double重载==运算符.反射器确认如下:
[__DynamicallyInvokable]
public static bool operator ==(double left, double right)
{
return (left == right);
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是看起来递归并且没有提到NaN特定的行为.那为什么它会返回假?
所以我添加了一些代码来区分
var x = "abc";
var y = "xyz";
Console.WriteLine(x == y); // => false
Run Code Online (Sandbox Code Playgroud)
现在我明白了
L_0001: ldc.r8 NaN
L_000a: stloc.0
L_000b: ldloc.0
L_000c: ldloc.0
L_000d: ceq
L_000f: call void [mscorlib]System.Console::WriteLine(bool)
L_0014: nop
L_0015: ldloca.s a
L_0017: ldloc.0
L_0018: call instance bool [mscorlib]System.Double::Equals(float64)
L_001d: call …Run Code Online (Sandbox Code Playgroud) 在.NET Framework中,实现(override中)Equals(object)和GetHashCode()浮点型(System.Double和System.Single)是错误的.引用MSDN GetHashCode(object)规范:
哈希函数必须具有以下属性:
•如果两个对象比较相等,则每个对象的GetHashCode方法必须返回相同的值.但是,如果两个对象的比较不相等,则两个对象的GetHashCode方法不必返回不同的值.
如果NaN使用具有不同二进制表示的两个值,则这两个对象在该Equals方法下比较相等,但哈希码(几乎总是)是不同的.
现在,Microsoft Connect 已报告此错误.但他们为什么不解决这个问题?
修复很简单:让不同的NaN 不比较相同,或选择一个固定的哈希代码返回任何NaN.
修复不会破坏任何东西:今天的方式,当使用不同的东西时没有任何作用NaN.
你能想出任何不解决这个问题的理由吗?
这是一个说明当前行为的简单示例:
using System;
using System.Collections.Generic;
using System.Linq;
static class Program
{
const int setSize = 1000000; // change to higher value if you want to waste even more memory
const double oneNaNToRuleThemAll = double.NaN;
static readonly Random randomNumberGenerator …Run Code Online (Sandbox Code Playgroud)