我在 C# (.Net 4) 中进行了一些统计操作,double[]
然后我发现CompareTo
方法和double.NaN
. 当我尝试这段代码时:
double.NaN.CompareTo(double.NegativeInfinity) //returns -1
这意味着double.NaN
比double.NegativeInfinity
! 谁能解释为什么会这样?
我在 C# (.Net 4) 中进行了一些统计操作,double[]
然后我发现CompareTo
方法和double.NaN
. 当我尝试这段代码时:
double.NaN.CompareTo(double.NegativeInfinity) //returns -1
这意味着double.NaN
比double.NegativeInfinity
! 谁能解释为什么会这样?
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的含义应该有助于阐明这两种方法试图表达的差异。
double.NaN
小于负无穷大。
从他们解释的元数据信息来看;
public const double NegativeInfinity = -1.0 / 0.0
public const double NaN = 0.0 / 0.0;
将此实例与指定的双精度浮点数进行比较,并返回一个整数,指示此实例的值是小于、等于还是大于指定的双精度浮点数的值。
如果此实例不是数字 (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 FF
和double.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
归根结底,将 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