一直很奇怪C#的預定義資料類型中為什麼加了一個decimal,有float和double不就夠了嗎?今天來挖一挖。
浮點型
Name | CTS Type | Description | Significant Figures | Range (approximate) |
---|---|---|---|---|
float | System.Single | 32-bit single-precision floating point | 7 | ±1.5 × 10−45 to ±3.4 × 1038 |
double | System.Double | 64-bit double-precision floating point | 15/16 | ±5.0 × 10 −324 to ±1.7 × 10308 |
如果我們在代碼中寫一個12.3,編譯器會自動認為這個數是個double型。是以如果我們想指定12.3為float類型,那麼你必須在數字後面加上F/f:
float f = 12.3F;
decimal類型
作為補充,decimal類型用來表示高精度的浮點數
Name | CTS Type | Description | Significant Figures | Range (approximate) |
---|---|---|---|---|
decimal | System.Decimal | 128-bit high precision decimal notation | 28 | ±1.0 × 10−28 to ±7.9 × 1028 |
從上表可以看出,decimal的有效位數很大,達到了28位,但是表示的資料範圍卻比float和double類型小。decimal類型并不是C#中的基礎類型,是以使用的時候會對計算時的性能有影響。
我們可以像如下的方式定義一個decimal類型的浮點數:
decimal d = 12.30M;
對decimal、float、double錯誤的認識
引用自:http://topic.csdn.net/t/20050514/20/4007155.html 中Ivony的評論
在精确計算中使用浮點數是非常危險的,盡管C#在浮點數運算時采取了很多措施使得浮點數運算的結果看起來是非常正常的。但實際上如果不清楚浮點數的特性而貿然使用的話,将造成非常嚴重的隐患。
考慮下面的語句:
double dd = 10000000000000000000000d;
dd += 1;
Console.WriteLine ( "{0:G50}", dd );
輸出是什麼?誰知道?
輸出是:1000000000000000000000000
這就是浮點數精度損失的問題,最重要的是,在精度損失的時候,不會報告任何的錯誤,也不會有任何的異常産生。
浮點數的精度損失可能在很多地方出現,例如d * g / g 不一定等于d,d / g * g也不一定等于d。
還有兩個非常危險的錯誤認識!!
1、decimal不是浮點型、decimal不存在精度損失。
下面有段程式大家可以去看看結果是什麼。記住!所有的浮點型變量都存在精度損失的問題,而decimal是一個不折不扣的浮點型,不論它精度有多高,精度損失依然存在!
decimal dd = 10000000000000000000000000000m;
dd += 0.1m;
Console.WriteLine ( "{0:G50}", dd );
2、decimal所能儲存的數比double大,從double到decimal的類型轉換不會出現任何問題。
微軟在decimal的幫助上真的要好好檢討了。實際上隻有從整形到decimal的轉換才是擴大轉換,decimal的精度比double大,但所能儲存的最大數卻比double要小。