对于double的比较,存在一些可能的坑,大家应该都清楚。比如容易注意的是double==double的精度问题。但是比较少注意的是double.NaN的比较
我们先看一个demo
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));
}
他的输出结果如下
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>
接口的需要,便于排序等操作的使用
所以说有什么代码推荐呢?
result=a>0?a:1
而不使用
result=a<=0?1:a
参考链接:
本文会经常更新,请阅读原文: https://xinyuehtx.github.io/post/%E5%B0%8F%E5%BF%83double%E7%9A%84%E6%AF%94%E8%BE%83.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名黄腾霄(包含链接: https://xinyuehtx.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。