您似乎很清楚使用浮點類型的好處。我傾向於在所有情況下設計小數點,並依靠分析器讓我知道小數點操作是否會導致瓶頸或減速。在這些情況下,我會「下注」來雙倍或浮動,但只能在內部完成,並且仔細嘗試通過限制正在執行的數學運算中的有效數字的數量來管理精度損失。
一般來說,如果你的值是瞬態的(不重用),你可以安全地使用浮點類型。浮點類型的真正問題是以下三種情況。
- 您正在聚集浮點值(在這種情況下,精度誤差化合物)
- 你建
- 你正在做數學與基於所述浮點值(例如在一個遞歸算法)值非常寬的數目的數字顯著(例如,
123456789.1 * .000000000000000987654321
)
EDIT
甲ccording到reference documentation on C# decimals:
的小數關鍵字表示 128位的數據類型。與 浮點類型相比,小數類型 具有更高的精度和更小的範圍,因此適用於 財務和貨幣計算。
所以澄清我的上述聲明:
我傾向於在所有 情況下爲小數設計,並依靠探查讓 我知道,如果在十進制運算是 造成瓶頸或慢-downs。
我只在有小數的行業工作過。如果您正在使用phsyics或圖形引擎,那麼設計浮點類型(float或double)可能會更有益處。
小數是不是無限精確的(這是不可能代表無限精度用於在原始數據類型非整數),但它遠遠大於雙更精確的:
- 小數= 28-29顯著數字
- 雙= 15-16顯著數字
- 浮子= 7個顯著數字
編輯2
迴應Konrad Rudolph的評論,項目#1(上述)絕對正確。不精確性的聚合確實複合了。請參見下面的代碼爲例:
private const float THREE_FIFTHS = 3f/5f;
private const int ONE_MILLION = 1000000;
public static void Main(string[] args)
{
Console.WriteLine("Three Fifths: {0}", THREE_FIFTHS.ToString("F10"));
float asSingle = 0f;
double asDouble = 0d;
decimal asDecimal = 0M;
for (int i = 0; i < ONE_MILLION; i++)
{
asSingle += THREE_FIFTHS;
asDouble += THREE_FIFTHS;
asDecimal += (decimal) THREE_FIFTHS;
}
Console.WriteLine("Six Hundred Thousand: {0:F10}", THREE_FIFTHS * ONE_MILLION);
Console.WriteLine("Single: {0}", asSingle.ToString("F10"));
Console.WriteLine("Double: {0}", asDouble.ToString("F10"));
Console.WriteLine("Decimal: {0}", asDecimal.ToString("F10"));
Console.ReadLine();
}
此輸出以下:
Three Fifths: 0.6000000000
Six Hundred Thousand: 600000.0000000000
Single: 599093.4000000000
Double: 599999.9999886850
Decimal: 600000.0000000000
正如你所看到的,即使我們從同一來源不斷增加,雙重的結果是少精確的(儘管可能會正確地回合),並且浮點數遠不夠精確,直到它減少到只有兩個有效數字。
另請參閱http://stackoverflow.com/questions/2545567/in-net-how-do-i-choose-between-a-decimal-and-a-double –
這得到upvoted相當有規律,我仍然奮鬥用它。例如,我正在開發一個用於財務計算的應用程序,因此我在整個過程中使用了十進制。但數學和VisualBasic.Financial函數使用雙重,所以有很多轉換,我不斷猜測使用小數。 –
@JamieIde這是瘋狂的金融功能使用雙倍,金錢應該始終在十進制。 –