浮點類型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);