对于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)判断相等性
而在<或>符号比较上NaN都是返回false,使用CompareTo方法与其他double比较时,NaN都是返回-1
微软的考虑是NaN不是一个数值,因此不能参与数值比较(比如NaN+1=NaN,那么前后的NaN是否相等呢?)。
而方法的比较是为了满足如IComparable<double>接口的需要,便于排序等操作的使用
所以说有什么代码推荐呢?
涉及可能会出现NaN的情况,需要使用double.IsNaN进行判断
涉及double的比较判断,建议使用True条件。
如判断a是否是正数,使用
C#result=a>0?a:1而不使用
C#result=a<=0?1:a
参考链接: