【问题标题】:CompareTo behaviour for double.NaN and double.NegativeInfinitydouble.NaN 和 double.NegativeInfinity 的 CompareTo 行为
【发布时间】:2013-01-04 22:16:49
【问题描述】:

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

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

这意味着double.NaNdouble.NegativeInfinity 还要小!谁能解释一下为什么会这样?

【问题讨论】:

  • 那么你的问题是什么?
  • 不,这意味着对于排序的情况,NaN被认为小于负无穷大。我冒昧地猜测,在将 NegativeInfinity 与 null 进行比较时遵循相同的规则。
  • 除了“这就是规范所说的那样”或者可能是一些疯狂的猜测之外,您不太可能得到任何答案。

标签: c# double nan infinity icomparable


【解决方案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 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
    

    【讨论】:

    • 呵呵 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
    

    【讨论】:

      猜你喜欢
      • 2012-02-07
      • 1970-01-01
      • 1970-01-01
      • 2014-06-02
      • 2011-07-09
      • 2012-05-31
      • 1970-01-01
      • 1970-01-01
      • 2013-01-05
      相关资源
      最近更新 更多