Akademisyenler öncülüğünde matematik/fizik/bilgisayar bilimleri soru cevap platformu
3 beğenilme 0 beğenilmeme
558 kez görüntülendi

Aşağıdaki kod parçasını Python'da çalıştıralım:

a=(0.1+0.2)+0.3
b=0.1+(0.2+0.3)

print(a==b)

Burada elbette a'nın b'ye eşit olması lazım. Ama Python da dahil olmak üzere çoğu programlama dili/yazılım için a ve b birbirine eşit çıkmaz. Yani en azından bu örnekte toplamanın birleşme özelliği yoktur. Bunun nedeni nedir?

Veri Bilimi kategorisinde (236 puan) tarafından  | 558 kez görüntülendi
Sanıyorum ki bu problem kullanılan programlama dilininin derleyicisi ve bilgisayarın Bit(32-64) özelliği ile alakalı.

çünkü 64 bit bilgisayar ile 32 bit bilgisayar arasında anlamlı rakamlar için fark vardır.belkide 128 bit bilgisayarımız olsa idi,bir C derleyiciside bu iki değeri eşit algılayabilirdi.

(acele ile yazıldı)

örneğin 32 bit bilgisayar 123,658 gösterirken

64 bit 123,65895613000 şeklinde gösterebilir.derleyicide muhtemelen anlamlı rakamlara göre problemi çözmektedir.
Belki bu iki değeri eşit algılayabilirdi, ama bu sefer de başka iki değeri eşit algılamazdı. Çünkü çoğu sayıyı temsil ederken yuvarlama hatası yapılmak zorundadır. İkili sayma sisteminde, irrasyonel sayılar ve paydası 2'nin kuvveti olmayan rasyonel sayılar bu şekilde temsil edildiğinde mutlaka yuvarlama hatası yapılır. Akıllı bir programlama ile bir rasyonel sayıyı floating point şeklinde temsil etmektense payını ve paydasını tamsayı olarak bellekte tutabilirsiniz ve işlemleri bu şekilde yapabilirsiniz belki. Ama irrasyonel sayılar için yapacak birşey yok.

1 cevap

3 beğenilme 0 beğenilmeme

Buradan görülebileceği gibi, günlük kullandığımız bilgisayarlarda tanımlanan virgüllü (floating point) sayılarda, virgülden sonra 16. basamaktan sonrası güvenilir değildir:

Bilgisayarın işlemcisinde ve belleğinde sayılar nasıl temsil edilir?

Burada a'yı hesaplarken önce 0.1+0.2 hesaplanır, hesaplanırken yuvarlama hatası yapılır, daha sonra bulunan sonuç 0.3 ile toplanır ve bir yuvarlama hatası daha yapılır. b'de de benzer şekilde 0.2+0.3 toplanıp bir yuvarlama hatası yapılır, sonra 0.1 ile toplanır. Bu iki sayının virgülden sonraki 16.basamağı (işlemci register'larında ise virgülden sonraki 52. basamağı) farklıdır. O yüzden karşılaştırma sonucunda bu iki sayı aynı çıkmaz.

Ama bu sorunlara önlem alınabilir. Emin değilim ama bildiğim kadarıyla bu kodu Mathematica'da yazarsanız a'nın b'ye eşit olduğunu görüyorsunuz. Bende olmadığı için deneyemiyorum. 

(236 puan) tarafından 
20,287 soru
21,826 cevap
73,514 yorum
2,592,940 kullanıcı