Double.NaN和double.NegativeInfinity的CompareTo行为

Hos*_*Rad 5 c# double icomparable nan infinity

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

double.NaN.CompareTo(double.NegativeInfinity) //returns -1
Run Code Online (Sandbox Code Playgroud)

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

tim*_*myl 7

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

这里的原因实际上取决于CLR中基元的设计行为.

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

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

double.NaN.CompareTo(double.NaN)
Run Code Online (Sandbox Code Playgroud)

将返回0.但是

double.NaN == double.NaN
Run Code Online (Sandbox Code Playgroud)

是假的.同样,

double.NaN.CompareTo(double.NegativeInfinity)
Run Code Online (Sandbox Code Playgroud)

返回-1,但是

double.NaN < double.NegativeInfinity
Run Code Online (Sandbox Code Playgroud)

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

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


Son*_*nül 6

double.NaN 小于负无穷大.

从元数据信息中他们解释说;

public const double NegativeInfinity = -1.0 / 0.0

public const double NaN = 0.0 / 0.0;
Run Code Online (Sandbox Code Playgroud)

Double.CompareTo()方法;

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

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

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

我们来看看这个样本(这是一个DEMO);

void Main()
{
    double a = double.NaN;
    double b = double.NegativeInfinity;
    Console.WriteLine(a.CompareTo(b));
}
Run Code Online (Sandbox Code Playgroud)

即使我们查看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
Run Code Online (Sandbox Code Playgroud)