5

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

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

这意味着double.NaNdouble.NegativeInfinity! 谁能解释为什么会这样?

4

3 回答 3

7

CompareTo 不会告诉您一件事比另一件事小。它告诉您在订购实例时一个实例在 (-) 之前、在 (+) 之后或可与 (0) 另一个实例互换。

这里的原因实际上取决于 CLR 中原语的设计行为。

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

请注意,CompareTo 在含义或预期用途上不一定与数字大于/小于运算相同。CompareTo 旨在为 double 可以采用的一组值提供排序。例如,

double.NaN.CompareTo(double.NaN)

将返回 0。但是

double.NaN == double.NaN

是假的。同样地,

double.NaN.CompareTo(double.NegativeInfinity)

返回 -1,但是

double.NaN < double.NegativeInfinity

返回假。因此,CompareTo 方法并不是说在数学上 double.NaN 小于 double.NegativeInfinity。小于运算符实际上说这不是真的。但它是说,在排序值时, double.NaN 排在第一位。

这里也是 Double 类型的LessThan Operator文档的链接。并排阅读它以及IComparable.CompareTo的含义应该有助于阐明这两种方法试图表达的差异。

于 2013-01-21T19:43:27.007 回答
7

double.NaN小于负无穷大。

从他们解释的元数据信息来看;

public const double NegativeInfinity = -1.0 / 0.0

public const double NaN = 0.0 / 0.0;

Double.CompareTo()方法;

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

如果此实例不是数字 (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.NegativeInfinity00 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
于 2013-01-21T19:31:49.980 回答
0

归根结底,将 double.nan 在数字上与任何东西进行比较是没有意义的。但是,如果你有一个 double 列表并想用它做点什么,你会希望它们都在列表的末尾,这样你就可以先做所有有意义的工作,这样当你看到第一个时你就可以停下来。这就像一个列表,其中一些项目为空,它们被推到最后。

出现 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
于 2014-09-11T19:15:37.477 回答