Double.NaN和double.NegativeInfinity的CompareTo行为

时间:2013-01-21 19:26:02

标签: c# double nan infinity icomparable

我正在使用double[]在C#(。Net 4)中进行一些统计操作,然后我发现CompareTo方法和double.NaN有一些奇怪的行为。当我尝试这段代码时:

double.NaN.CompareTo(double.NegativeInfinity) //returns -1

这意味着double.NaN甚至小于double.NegativeInfinity!任何人都能解释为什么会这样吗?

3 个答案:

答案 0 :(得分:7)

CompareTo并没有告诉你一件事比另一件小。它告诉你一个实例在( - )之后,跟随(+)或在订购实例时可以与(0)另一个实例互换。

为什么这里真的取决于CLR中基元的设计行为。

IComparable的目的是排序类型的实例。因此,对于NaN,一个有效的double值,决定在之前对该类型的任何其他实例进行排序。

请注意,CompareTo在含义或用途上不一定相同,因为数字大于/小于操作。 CompareTo旨在提供双倍可以承担的值集合的排序。例如,

double.NaN.CompareTo(double.NaN)

将返回0.但是

double.NaN == double.NaN

是假的。同样地,

double.NaN.CompareTo(double.NegativeInfinity)

返回-1,但

double.NaN < double.NegativeInfinity

返回false。因此,CompareTo方法并不是说数学上是double.NaN小于double.NegativeInfinity。事实上,小于运营商说这不是真的。但是它说,在订购价值时,double.NaN首先出现。

以下是Double类型的LessThan Operator文档的链接。同时阅读IComparable.CompareTo的含义应该有助于澄清两种方法试图表达的差异。

答案 1 :(得分:6)

double.NaN小于负无穷大。

从他们解释的元数据信息中可以看出;

public const double NegativeInfinity = -1.0 / 0.0

public const double NaN = 0.0 / 0.0;

来自Double.CompareTo()方法;

  

将此实例与指定的双精度浮点值进行比较   number并返回一个整数,指示是否为this的值   instance小于,等于或大于the的值   指定的双精度浮点数。

如果此实例不是数字(NaN)且值是数字

Double.CompareTo()方法返回负整数

我们来看看这个示例(这里是 DEMO );

void Main()
{
    double a = double.NaN;
    double b = double.NegativeInfinity;
    Console.WriteLine(a.CompareTo(b));
}

即使我们查看IL代码,double.NaN代表00 00 00 00 00 00 F8 FFdouble.NegativeInfinity代表00 00 00 00 00 00 F0 FF;

IL_0000:  ldc.r8      00 00 00 00 00 00 F8 FF 
IL_0009:  stloc.0     
IL_000A:  ldc.r8      00 00 00 00 00 00 F0 FF 
IL_0013:  stloc.1     
IL_0014:  ldloca.s    00 
IL_0016:  ldloc.1     
IL_0017:  call        System.Double.CompareTo
IL_001C:  call        System.Console.WriteLine

答案 2 :(得分:0)

在一天结束时,将double.nan数字与任何事物进行比较是毫无意义的。但是如果你有一个双重列表并希望对它做一些事情,那么你需要在列表末尾全部完成它们,这样你就可以先做所有有意义的工作,这样你就可以在看到第一个时停下来一。它就像一个列表,其中一些项目为空,它们被推到最后。

发生double.nan的一些情况:

Dim d1 as double = 0/0
Dim d2 as double = Double.PositiveInfinity / Double.PositiveInfinity
Dim d3 as double = Double.PositiveInfinity / Double.NegativeInfinity
Dim d4 as double = Double.PositiveInfinity / Double.PositiveInfinity
Dim d5 as double = Double.PositiveInfinity / Double.NegativeInfinity