Skip to content

对于double的比较,存在一些可能的坑,大家应该都清楚。比如容易注意的是double==double的精度问题。但是比较少注意的是double.NaN的比较

我们先看一个demo

C#
public static void Main()
   {
      Console.WriteLine("NaN == NaN: {0}", Double.NaN == Double.NaN); 
      Console.WriteLine("NaN != NaN: {0}", Double.NaN != Double.NaN); 
      Console.WriteLine("NaN.Equals(NaN): {0}", Double.NaN.Equals(Double.NaN)); 
      Console.WriteLine("! NaN.Equals(NaN): {0}", ! Double.NaN.Equals(Double.NaN)); 
      Console.WriteLine("IsNaN: {0}", Double.IsNaN(Double.NaN));

      Console.WriteLine("\nNaN > NaN: {0}", Double.NaN > Double.NaN); 
      Console.WriteLine("NaN >= NaN: {0}", Double.NaN >= Double.NaN); 
      Console.WriteLine("NaN < NaN: {0}", Double.NaN < Double.NaN);
      Console.WriteLine("NaN < 100.0: {0}", Double.NaN < 100.0); 
      Console.WriteLine("NaN <= 100.0: {0}", Double.NaN <= 100.0); 
      Console.WriteLine("NaN >= 100.0: {0}", Double.NaN > 100.0);
      Console.WriteLine("NaN.CompareTo(NaN): {0}", Double.NaN.CompareTo(Double.NaN)); 
      Console.WriteLine("NaN.CompareTo(100.0): {0}", Double.NaN.CompareTo(100.0)); 
      Console.WriteLine("(100.0).CompareTo(Double.NaN): {0}", (100.0).CompareTo(Double.NaN)); 
   }

他的输出结果如下

C#
NaN == NaN: False
NaN != NaN: True
NaN.Equals(NaN): True
! NaN.Equals(NaN): False
IsNaN: True

NaN > NaN: False
NaN >= NaN: False
NaN < NaN: False
NaN < 100.0: False
NaN <= 100.0: False
NaN >= 100.0: False
NaN.CompareTo(NaN): 0
NaN.CompareTo(100.0): -1
(100.0).CompareTo(Double.NaN): 1

我们可以看到,在相等性上,NaN!=NaN,但是可以使用NaN.Equals(NaN)判断相等性

而在&lt;&gt;符号比较上NaN都是返回false,使用CompareTo方法与其他double比较时,NaN都是返回-1

微软的考虑是NaN不是一个数值,因此不能参与数值比较(比如NaN+1=NaN,那么前后的NaN是否相等呢?)。

而方法的比较是为了满足如IComparable&lt;double&gt;接口的需要,便于排序等操作的使用

所以说有什么代码推荐呢?

  • 涉及可能会出现NaN的情况,需要使用double.IsNaN进行判断

  • 涉及double的比较判断,建议使用True条件。

    如判断a是否是正数,使用

    C#
    result=a>0?a:1

    而不使用

    C#
    result=a<=0?1:a

参考链接:

最后更新于:

基于 VitePress + @sugarat/theme 构建