这个stackoverflow问题提出了一个关于使用NaN值对双数组进行排序的有趣问题.OP发布了以下代码:
static void Main(string[] args)
{
double[] someArray = { 4.0, 2.0, double.NaN, 1.0, 5.0, 3.0, double.NaN, 10.0, 9.0, 8.0 };
foreach (double db in someArray)
{
Console.WriteLine(db);
}
Array.Sort(someArray);
Console.WriteLine("\n\n");
foreach (double db in someArray)
{
Console.WriteLine(db);
}
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
在.NET 3.5框架下运行时,数组按如下方式排序:
1,4,NaN,2,3,5,8,9,10,NaN
当您在.NET 4.0下运行它时,数组的逻辑排序更为一些:
NaN,NaN,1,2,3,4,5,8,9,10
我可以理解为什么它会在.NET 3.5中奇怪地排序(因为NaN不等于,小于或大于任何东西).我也可以理解为什么它会像在.NET 4.0中那样排序.我的问题是,为什么这个从3.5变为4.0?这个变化的Microsoft文档在哪里?
Han*_*ant 38
这是一个bug修复.带有错误详细信息的反馈报告就在这里.微软对错误报告的回应:
请注意,此错误会影响以下内容:
- Array.Sort(),其中数组包含Double.NaN
- Array.Sort(),其中数组包含Single.NaN
- 任何上面的调用者,例如在List.Sort()上,其中list包含Double.NaN
此错误将在运行时的下一个主要版本中修复; 在此之前,您可以使用执行正确排序的自定义IComparer来解决此问题.正如变通方法注释中所提到的,不要使用Comparer.Default,因为这是特殊情况下的快捷排序例程,无法正确处理NaN.相反,您可以提供自己的比较器,提供相同的比较,但不会是特殊的比较.
不是一个真正的答案,但也许是一个线索......您可以使用以下代码重现4.0中奇怪的3.5行为:
void Main()
{
double[] someArray = { 4.0, 2.0, double.NaN, 1.0, 5.0, 3.0, double.NaN, 10.0, 9.0, 8.0 };
Array.Sort(someArray, CompareDouble);
someArray.Dump();
}
int CompareDouble(double a, double b)
{
if (a > b)
return 1;
if (a < b)
return -1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这里,无论是a > b和a < b返回false,如果A或B NaN,所以CompareDouble方法返回0,所以NaN被认为是等于一切......这给了相同的结果3.5:
1,4,NaN,2,3,5,8,9,10,NaN
Run Code Online (Sandbox Code Playgroud)