首页 > 技术文章 > 老鼠, 老虎傻傻分不清楚之Double.NaN

wangn 2014-03-20 09:33 原文

 

    如果看到这段代码,客官您认为会输出什么?

    

static void Main(string[] args)
        {

            double tmpValue=double.NaN;
            if(tmpValue==double.NaN)
            {
                Console.WriteLine("这是正常输出?");
            }
            else
            {
                Console.WriteLine("这是神马情况?");
            }
          
            Console.Read();
        }

  如果是"这是正常输出?",恭喜您!     可以去面壁了!

   哈哈,不过玩数据库的同学都知道这个东西看上去会感觉不对劲,但是也不好说是哪里不对。

     其实结果是:

     

 

     下面详细说一下:

public const double NaN = 0.0 / 0.0;

表示不是数字 (NaN) 的值。 此字段为常数。

  有的同学会说我知道了,因为NaN的值是0.0/0.0,那么写成这个样子输出是什么呢?

     

  double tmpValue = double.NaN;
            if ((0.0/0.0) == double.NaN)
            {
                Console.WriteLine("这是正常输出?");
            }
            else
            {
                Console.WriteLine("这是神马情况?");
            }

   其实结果是和上面一样的。MSDN上的游戏法则:

   当未定义算术运算时,Double.NaN 表示非数字结果。 测试一个值与 Double.NaN 之间的相等关系的任何表达式始终返回 false。 测试一个值与 Double.NaN 之间的不等关系的任何表达式始终返回 true。

如何解决冲突。若要修复与此规则的冲突并准确确定某个值是否表示 Double.NaN,请使用 Single.IsNan 或 Double.IsNan 来测试值。

     翻开Double类的源代码会发现:

       

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        public static bool IsNaN(double d) 
        { 
            //Jit will generate inlineable code with this
// warning CS1718: comparison to same variable 
#pragma warning disable 1718
            if (d != d)
            {
                return true; 
            }
            else 
            { 
                return false;
            } 
#pragma warning restore 1718
        }

         至于:ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)是什么意思,请大家参阅MSDN。至于数据库的Null判断也是is null 不要搞错了哦,否则坑太深不容易出来 。^_^

 

      另这个扩展阅读(这个Attribute在Object类中的作用)

      http://kb.cnblogs.com/page/69614/

 

推荐阅读