Kayan nokta türü kullanmanın yararlarına dikkat çekiyorsunuz. Her durumda ondalıklar için tasarım yapmaya eğilimliyim ve ondalık işlemlerin darboğazlara veya yavaşlamalara neden olup olmadığını bana bildirmek için bir profillere güveniyorum. Bu durumlarda, ikiye katlamak veya yüzmek için "aşağı dökeceğim", ancak sadece dahili olarak yapacağım ve yapılan matematiksel işlemdeki önemli basamakların sayısını sınırlayarak hassas kaybı yönetmeye dikkatle çalışacağım.
Genel olarak, değeriniz geçici ise (tekrar kullanılmıyorsa) bir kayan nokta türü kullanmak güvenlidir. Kayan nokta türleri ile ilgili asıl sorun aşağıdaki üç senaryodur.
- Kayan nokta değerlerini topluyorsunuz (bu durumda hassas hatalar bileşiği)
- Kayan nokta değerine dayalı değerler oluşturursunuz (örneğin, özyinelemeli algoritmada)
- Çok sayıda önemli basamakla matematik yapıyorsunuz (örneğin,
123456789.1 * .000000000000000987654321
)
DÜZENLE
C # ondalık sayılara ilişkin referans belgelerine göre :
Ondalık anahtar 128 bitlik veri türünü gösterir. Kayan noktalı türlerle karşılaştırıldığında, ondalık tür daha büyük bir hassasiyete ve daha küçük bir aralığa sahiptir, bu da onu finansal ve parasal hesaplamalar için uygun hale getirir.
Yukarıdaki açıklamamı netleştirmek için:
Her durumda ondalıklar için tasarım yapmaya eğilimliyim ve ondalık işlemlerin darboğazlara veya yavaşlamalara neden olup olmadığını bana bildirmek için bir profillere güveniyorum.
Sadece ondalık sayıların elverişli olduğu sektörlerde çalıştım. Fizik veya grafik motorları üzerinde çalışıyorsanız, kayan nokta tipi (float veya double) için tasarlamak çok daha yararlıdır.
Ondalık sınırsız derecede kesin değildir (ilkel bir veri türünde integral olmayan için sonsuz hassasiyeti temsil etmek imkansızdır), ancak çiftten çok daha kesindir:
- ondalık = 28-29 anlamlı basamak
- çift = 15-16 anlamlı basamak
- kayan nokta = 7 anlamlı basamak
DÜZENLEME 2
Konrad Rudolph'un yorumuna cevaben , 1. madde (yukarıda) kesinlikle doğrudur. Tutarsızlığın bir araya gelmesi gerçekten bileşiktir. Bir örnek için aşağıdaki koda bakın:
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();
}
Bu, aşağıdakileri çıkarır:
Three Fifths: 0.6000000000
Six Hundred Thousand: 600000.0000000000
Single: 599093.4000000000
Double: 599999.9999886850
Decimal: 600000.0000000000
Gördüğünüz gibi, aynı kaynak sabitinden eklememize rağmen, çiftin sonuçları daha az kesindir (muhtemelen doğru bir şekilde yuvarlansa da) ve şamandıra çok daha az hassastır, sadece azaltıldığı noktaya kadar iki önemli basamak.