double.NaN 和 double.NegativeInfinity 的 CompareTo 行为
Posted
技术标签:
【中文标题】double.NaN 和 double.NegativeInfinity 的 CompareTo 行为【英文标题】:CompareTo behaviour for double.NaN and double.NegativeInfinity 【发布时间】:2013-01-04 22:16:49 【问题描述】:我在 C# (.Net 4) 中使用 double[]
进行一些统计操作,然后我发现使用 CompareTo
方法和 double.NaN
的一些奇怪行为。当我尝试这段代码时:
double.NaN.CompareTo(double.NegativeInfinity) //returns -1
这意味着double.NaN
比double.NegativeInfinity
还要小!谁能解释一下为什么会这样?
【问题讨论】:
那么你的问题是什么? 不,这意味着对于排序的情况,NaN被认为小于负无穷大。我冒昧地猜测,在将 NegativeInfinity 与 null 进行比较时遵循相同的规则。 除了“这就是规范所说的那样”或者可能是一些疯狂的猜测之外,您不太可能得到任何答案。 【参考方案1】: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 的含义应该有助于阐明这两种方法试图表达的差异。
【讨论】:
【参考方案2】:double.NaN
小于负无穷大。
来自他们解释的元数据信息;
public const double NegativeInfinity = -1.0 / 0.0
public const double NaN = 0.0 / 0.0;
来自Double.CompareTo()
方法;
将此实例与指定的双精度浮点数进行比较 number 并返回一个整数,表示 this 的值是否 实例小于、等于或大于 指定的双精度浮点数。
如果这个实例不是一个数字(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
【讨论】:
呵呵 MSDN 不正确:Double.NaN.CompareTo(double.NaN) 返回 0,而不是 -1。 幸运。 :-) 好吧,我承认,当它们都是 NaN 时,MSDN 告诉它是 0。 @StefandeBruijn MSDN 是对的。它说 此实例和值都不是数字 (NaN)、PositiveInfinity 或 NegativeInfinity。它返回零。所以我认为 MSDN 是正确的。 是的,我首先阅读了您不完整信息的答案,然后在 MSDN 上看到了它。你只是对我来说编辑得太快了;-)【参考方案3】:归根结底,将 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
【讨论】:
以上是关于double.NaN 和 double.NegativeInfinity 的 CompareTo 行为的主要内容,如果未能解决你的问题,请参考以下文章