Çözüldü C# double veri türü 15.basamak hassasiyeti

Bu konu çözüldü olarak işaretlenmiştir. Çözülmediğini düşünüyorsanız konuyu rapor edebilirsiniz.

bugzone2.0

Hectopat
Katılım
17 Şubat 2018
Mesajlar
471
Makaleler
1
Çözümler
5
Yer
İzmit/KOCAELİ
Daha fazla  
Cinsiyet
Erkek
Meslek
Jr. Java Back-end Developer
C#:
double deger = 8.123456789123458;
Console.WriteLine("Double Türündeki Değer : {0}",deger);

Yukarıda örneğini vermiş olduğum kodun ekran çıktısında 15. hanede bulunan 8 sayısı 7 olarak çıkıyor.
Aynı sayının son hanesi.
1 ıse 0.
2 ıse 2 (denk)
3 ıse 4.
4 ıse 4 (denk)
5 ıse 5 (denk)
6 ıse 5.
7 ıse 7 (denk)
8 ıse 7.
9 ıse 9 (denk)
Rakamlarına yuvarlanıyor. Aralarında matematiksel bir ilişki kuramadım, kimi sayıda yuvarlama yapıyor kimi sayıda yuvarlama yapmıyor. Yaptığı yuvarlamada bir mantık da göremedim bunun sebebi nedir?
Dipnot: C# double veri türü virgülden sonra 15 haneye kadar duyarlıdır.
Benim sorum 15. hanedeki yuvarlama mantığı. Yuvarlama mantığında 5 altı 0'a 5 ve üzeri 10'a yuvarlanır.
Yine farklı bir şekilde değer verdiğimizde yukarıda bulunan 1 ise 0 yapma durumu değişiyor.
Örneğin;

C#:
double deger = 8.000000000000001;

İlk örnekte 15. hanede 1 rakamını 0 yapan derleyici ikinci örnekte 1 rakamını 2 yapıyor.

Bu konu hakkında bilgi sahibi olan var mı?
 
Çözüm
IEEE standartlari sebebiyle.

C# mantissa boyutunu kac tutuyor bilmiyorum ama, 15. basamaktaki hassasiyet bias sebebiyle her zaman dogru reprezente edilmiyor olabilir.

Bunda bir yanlislik yok.

15. basamaktaki decimal deger, binary olarak 64 bit (mantissa + exponent) ikilisiyle dogru gosterilemiyor, sebep bu. Bias her sayiya gore degisir. Ustteki linkten inceleyebilirsiniz.

"The exponent field needs to represent both positive and negative exponents. To do this, a bias is added to the actual exponent in order to get the stored exponent."

(bias, burada dikkat etmeniz gereken farklilik )

Java'daki BigDecimal'a denk gelen C# class'ini kullanip arbitrary hassasiyet elde edebilirsiniz memory'den feragat ederek.
Bu bir yuvarlama hatası.


Burda İngilizce olarak anlatılmış durum. Çevirmek istemedim, zira bozuluyor:


C#:
double deger_double = 8.123456789123458;
Console.WriteLine("Double  Türündeki Değer : {0}",deger_double);
        
decimal deger_decimal = 8.123456789123458M;
Console.WriteLine("Decimal Türündeki Değer : {0}",deger_decimal);

Arkadaşlar konuya matematiksel net bir cevap dışında bir yorum yapıp bilgi kirliliğine yol açmayalım.

Bilgi kirliliği göremiyorum. Eğer siz görüyorsanız, rapor edebilirsiniz.

@Vavien. gayet mantıklı bir yaklaşımda bulunmuş.
 
Son düzenleme:
Sayın Aydoğdu lütfen bunu da dikkate alın.

Bence olay değişken türlerinin bellekte ayırdığı alan ile ilgili. Bahsettiğiniz 32 ve 64 bitler de bununla alakalı zaten. Bellekte her bir sayı 4 bitlik bir alan kaplıyor. 64 / 4'de 16 ediyor.
 
Artı -2 Eksi
IEEE standartlari sebebiyle.

C# mantissa boyutunu kac tutuyor bilmiyorum ama, 15. basamaktaki hassasiyet bias sebebiyle her zaman dogru reprezente edilmiyor olabilir.

Bunda bir yanlislik yok.

15. basamaktaki decimal deger, binary olarak 64 bit (mantissa + exponent) ikilisiyle dogru gosterilemiyor, sebep bu. Bias her sayiya gore degisir. Ustteki linkten inceleyebilirsiniz.

"The exponent field needs to represent both positive and negative exponents. To do this, a bias is added to the actual exponent in order to get the stored exponent."

(bias, burada dikkat etmeniz gereken farklilik )

Java'daki BigDecimal'a denk gelen C# class'ini kullanip arbitrary hassasiyet elde edebilirsiniz memory'den feragat ederek.
 
Çözüm

Konu Microsoft tarafından da mantissa + exponent durumuyla açıklanmış.

0.1 * 10 ile 10 kere 0.1 toplamının eşit olmayışı buna örnek.

Konuya kaynaklar ile cevap veren arkadaşlara teşekkür ediyorum. Soruyu okuma zahmetinde bulunduğunuz için ayrıca teşekkürler. Soru çözülmüştür.

Microsoft kaynağı: Microsoft Double Struct
 
Bu siteyi kullanmak için çerezler gereklidir. Siteyi kullanmaya devam etmek için çerezleri kabul etmelisiniz. Daha Fazlasını Öğren.…