浮点类型的特殊性知多少

浮点类型float和double有一些特殊性,比如他们处理精度的方式,在比较两个值是否相等时,浮点类型的不准确性可能会造成非常严重的后果。有时候本来应该是相等值,最后一比较却别的不想等了。

一次很简单的赋值可能就会将引发精度问题,比如double number=140.6F。由于double能容纳的比float更加精确的值,所以C#编译器实际上会将这个表达式解释成double number=140.600 0061 0351 6。而这个值作为一个float确实是140.6,但表示成一个double的时候,并不能准确度地等于140.6

 

 static void TestMethod1()
        {
            decimal decimalnumber = 4.2M;
            double doubleNumber1 = 0.1F * 42F;
            double doubleNumber2 = 0.1D * 42D;
            double floatNumbler = 0.1F * 42F;
            Trace.Assert(decimalnumber !=(decimal)doubleNumber1);
            Trace.Assert((double)decimalnumber != doubleNumber1);
            Trace.Assert((float)decimalnumber != floatNumbler);
            Trace.Assert(4.2F != 4.2D);
        }

 为了避免浮点类型的不准确性而造成的非预期的结果,开发者应该避免使用这些类型来构建相等性条件。相反,相等性条件应该包含一个容差,为此,一个简单的办法就是用一个值减去另一个值,然后计算结果的绝对值是否小于最大容差。另外,更好的方案是使用decimal类型,而不是浮点类型。

另外,浮点类型还有其他的一些特殊性质,例如,一个整数除以零理论上应该是错误的。这对于精确类型的Int,decimal这一点都是成立的。然而对于浮点类型float和double允许一些特殊值,例如:

float f=0f;

System.Console.Write(f/0);

posted @ 2012-06-03 00:34  chunchill  阅读(428)  评论(0编辑  收藏  举报