浮點型別:科學計算主力
| 型別 | .NET 類型 | 位元 | 範圍 | 有效數字 | 用途 |
float | System.Single | 32 | ±1.5×10⁻⁴⁵ ~ ±3.4×10³⁸ | 7 位 | 一般科學計算、圖形、遊戲 |
double | System.Double | 64 | ±5.0×10⁻³²⁴ ~ ±1.7×10³⁰⁸ | 15-16 位 | 預設浮點、高精度科學計算 |
效能權衡:float 運算較快、佔半記憶體;大量資料處理優先考慮。double 為 C# 浮點字面值預設型別(1.5 是 double)。
Decimal 型別:金融計算專用
| 特性 | 數值 |
| 位元數 | 128 |
| 有效數字 | 28-29 位 |
| 範圍 | ±1.0×10⁻²⁸ ~ ±7.9×10²⁸ |
| 精度單位 | 位數,非小數位 |
| 運算精度 | 準確至 28 小數位 |
關鍵差異:二進位 vs 十進位
// 二進位浮點無法精確表示 0.1
float f = 0.1f; // 實際儲存 ≈ 0.10000000149
double d = 0.1; // 實際儲存 ≈ 0.10000000000000001
// Decimal 精確表示 0.1
decimal m = 0.1m; // 精確 0.1
// 金融計算範例
decimal price = 19.99m;
decimal tax = price * 0.05m; // 精確 0.9995
double badTax = 19.99 * 0.05; // 可能產生 0.9994999999999999
Decimal 字面值後綴 m/M
decimal d1 = 10.5m; // ✅ 正確
decimal d2 = 10.5; // ⚠️ 先視為 double 再隱性轉換,可能精度損失
decimal d3 = 10m; // 整數也建議加 m
精度陷阱與避坑指南
| 陷阱 | 說明 | 解法 |
| 浮點比較 | 0.1 + 0.2 == 0.3 為 false | 用 Math.Abs(a-b) < epsilon 或 Decimal |
| 累加誤差 | 迴圈加 0.1 千次結果偏移 | Decimal 或整數分單位(分/厘)運算 |
| 大數吃小數 | 1e20 + 1 == 1e20 (double) | 避免極大極小數混合運算 |
| ToString 顯示 | 預設截斷,隱藏真實儲存值 | value.ToString("R") 圓整往返格式 |
選擇決策樹
- 金融/貨幣/精確十進位需求 → Decimal
- 科學工程/圖形/物理模擬/大範圍 → Double
- 記憶體受限/GPU 傳輸/大量陣列/精度要求低 → Float
進階:IEEE 754 特殊值
NaN:非數字(0.0/0.0)
Infinity:無窮大(1.0/0.0)
-Infinity:負無窮大
float.IsNaN()、double.IsInfinity() 檢測
總結
記住核心原則:錢用 Decimal,科學用 Double,記憶體受限用 Float。理解二進位浮點本質限制,避免金融計算精度災難。