Arama butonu
Bu konudaki kullanıcılar: 1 misafir
17
Cevap
1778
Tıklama
2
Öne Çıkarma
Python başlangıç seviyesinde aldığım ilginç hata
G
5 yıl
Yüzbaşı
Konu Sahibi

Merhaba,

Salgın günlerinde sıkıntıdan kodlama öğreneyim dedim ve pythona başladım.

Dairenin çevresini hesaplarken ekte gösterdiğim gibi bana ilginç gelen hatalı bir sonuç alıyorum. Bunun neden böyle olduğunu bilen var mı?

Kısaca özetleyeyim
Pi değişkenine 3.14 değerini veriyorum
r yarıçapı input ile giriş yaptiriyorum
Dairenin cevresi formülüyle 2*pi*r olarak hesaplatiyorum.

Yaricapa 10 değerini verdigimde çevre 62.800000004 gibi saçma şekilde kusuratli çıkıyor. Yaricapa 10 dışında hangi değeri verirsem sonuç doğru çıkıyor sadece 10 değerini verdigimde sonuca saçma bir kusurat ekliyor.
Bu neden oluyor. Bilen var mı?


< Resime gitmek için tıklayın >

DH forumlarında vakit geçirmekten keyif alıyor gibisin ancak giriş yapmadığını görüyoruz.

Üye olduğunda özel mesaj gönderebilir, beğendiğin konuları favorilerine ekleyip takibe alabilir ve daha önce gezdiğin konulara hızlıca erişebilirsin.

Üye Ol Şimdi Değil



< Bu ileti mobil sürüm kullanılarak atıldı >

G
5 yıl
Yüzbaşı

Çünkü bilgisayar sayıları decimal değil de binary şeklinde depolar. Büyük ihtimalle sonuç yuvarlanıyor. Kaç basamak kullanacağını belirleyip öyle print edebilirsin.



K
5 yıl
Yüzbaşı

Rakamın en sonunda bir tane dört var. Diğerlerinde 16. sayıdan önce bir küsürat yok ve bu nedenle gereksiz sıfırları göstermiyor. 5 veya 20 veya 40 ta da aynı şekilde çıkıyor.



G
5 yıl
Yüzbaşı
Konu Sahibi

Zaten bahsettiğim hata orada çıkan saçma kusurat. Orada çıkan ,00000000004 kusuratinin cikmamasi lazım.

r=10 değerini verdigimde yani yarıçap 10 dediğimde çemberin çevresi hesaba göre (2 * 3,14 * 10) = 62,80 çıkması lazım ama ne hikmetse python sonucu 62,800000000004 gibi alakasız bir sonuç veriyor.

Yani demek istediğim orada çıkan 00000000004 kusurati hatalı. Yaricapa başka hangi sayıyı verirsem verim sonucu doğru hesaplıyor ama 10 verdigimde anlamsız bir hesap hatası yapıyor. Bu durum koskoca dünyada bitek benim başıma gelmiş olamaz heralde :)

@K110 arkadaşımızın dediği gibi 5, 10, 20, 40, 80, 160 .... şeklinde tüm sayılarda hatalı sonuç veriyor. Diğer rakamları denediğimizde sonuç doğru çıkıyor.

< Resime gitmek için tıklayın >





< Bu mesaj bu kişi tarafından değiştirildi girdap7 -- 14 Mayıs 2020; 7:45:33 >

< Bu ileti mobil sürüm kullanılarak atıldı >
Bu mesaja 1 cevap geldi.
G
5 yıl
Yüzbaşı

Hata değil o.

Float değişkeni tanımlandığınızda RAM'de 64 bitlik bir alan açılıyor. O alana girdiğiniz sayı binary formatına çevrilip depo ediliyor. Ancak decimal değerde normal gözüken bir sayısı binary formatında sonsuza giden sayılara sahip olabilir. En klasik örneği 1/3 = 0.33333... gibi. Alan sınırlı olduğu için Python belli bir değer kadar depoluyor ama alan dolunca orada kalıyor. Sonra siz o sayısı çağırınca tekrar decimal değere çeviriyor ve sonuç öyle çıkıyor.





< Bu mesaj bu kişi tarafından değiştirildi Guest-06D4C1909 -- 14 Mayıs 2020; 6:42:53 >
Bu mesaja 2 cevap geldi.

Bu mesajda bahsedilenler: @girdap7
G
5 yıl
Yüzbaşı
Konu Sahibi

quote:

Orijinalden alıntı: Guest-06D4C1909

Hata değil o.

Float değişkeni tanımlandığınızda RAM'de 64 bitlik bir alan açılıyor. O alana girdiğiniz sayı binary formatına çevrilip depo ediliyor. Ancak decimal değerde normal gözüken bir sayısı binary formatında sonsuza giden sayılara sahip olabilir. En klasik örneği 1/3 = 0.33333... gibi. Alan sınırlı olduğu için Python belli bir değer kadar depoluyor ama alan dolunca orada kalıyor. Sonra siz o sayısı çağırınca tekrar decimal değere çeviriyor ve sonuç öyle çıkıyor.
Bilgi için teşekkürler. sizin dediğinize göre ben yarıçapa 10 değerini girdiğimde aslında 10,0000000000000001 gibi bir değer olarak mı algılıyor. sonucu hatalı çıkaran örnek rakamları aşağıdaki görüntüde gösterdim. neticede sizin dediğiniz gibi bile olsa sonuç hatalı çıkmış oluyor. yanı bu hesapta ve sonuçta hata var. doğru hesap yapmıyor. yani bazı rakamlarda doğru hesap yaparken bazı rakamlarda hatalı hesap yapıyor :)

< Resime gitmek için tıklayın >


Bu mesaja 1 cevap geldi.
G
5 yıl
Yüzbaşı
Konu Sahibi

quote:

Orijinalden alıntı: Guest-06D4C1909

Hata değil o.

Float değişkeni tanımlandığınızda RAM'de 64 bitlik bir alan açılıyor. O alana girdiğiniz sayı binary formatına çevrilip depo ediliyor. Ancak decimal değerde normal gözüken bir sayısı binary formatında sonsuza giden sayılara sahip olabilir. En klasik örneği 1/3 = 0.33333... gibi. Alan sınırlı olduğu için Python belli bir değer kadar depoluyor ama alan dolunca orada kalıyor. Sonra siz o sayısı çağırınca tekrar decimal değere çeviriyor ve sonuç öyle çıkıyor.
değişkeni integer yaparak aldığımda da aynı sonuçlar çıktı. hata acaba tanımladığım pi = 3.14 değerinde mi?


< Resime gitmek için tıklayın >



G
5 yıl
Yüzbaşı

Demek istediğim şu aslında: Senin hafızan en fazla 5 basamak tutabiliyor olsun. O nedenle 123/999 işleminin sonucunu 0.1231 diye tutabilirsin. Benim hafızam ise 10 basamak tutarsa aynı işlemin sonucunu 0.123123123 tutar. Şimdi çıkan sonuçları kıyaslarsak hatalı işlem mi yapmış oluyoruz? Sayıların farklı çıkması işlem hatasından ötürü mü yoksa hafıza büyüklüklerinin farklı olmasından ötürü mü?





< Bu mesaj bu kişi tarafından değiştirildi Guest-06D4C1909 -- 14 Mayıs 2020; 7:33:59 >
Bu mesaja 1 cevap geldi.

Bu mesajda bahsedilenler: @girdap7
G
5 yıl
Yüzbaşı
Konu Sahibi

quote:

Orijinalden alıntı: Guest-06D4C1909

Demek istediğim şu aslında: Senin hafızan en fazla 5 basamak tutabiliyor olsun. O nedenle 123/999 işleminin sonucunu 0.1231 diye tutabilirsin. Benim hafızam ise 10 basamak tutarsa aynı işlemin sonucunu 0.123123123 tutar. Şimdi çıkan sonuçları kıyaslarsak hatalı işlem mi yapmış oluyoruz? Sayıların farklı çıkması işlem hatasından ötürü mü yoksa hafıza büyüklüklerinin farklı olmasından ötürü mü?
o mevzuyu anladım ben, virgülden sonra kaç basamağa kadar aldığına göre sonuç değişir ama benim yaptığım bu basit örnekte böyle bir konu yok.

pi = 3,14
r= 10

Dairenin çevresi : 2*pi*r

(2) * (3,14) * (10) = (62,80)
Yani kağıt kalemle veya hesap makinesiyle yaptığımızda sonuç 62,80 çıkar. öss sınavında bu soru çıkarsa işaretleyeceğimiz şık 62,80 dir :)

ama python aynı verilerle sonucu (62,80000000000004) olarak hesaplıyor.

şimdi burada pythona girdiğimiz hangi veride problem var? pi=3,14 mü? r=10 mu? yoksa girdiğim formülde mi hata var?


Bu mesaja 1 cevap geldi.
G
5 yıl
Yüzbaşı

Sanırım anlatma becerim zayıf. Anlaşamadığımız nokta şu: Senin hata yok dediğin kısım onluk sayma (decimal) sayı sisteminde. Bilgisayar ise o işlemi ikilik sayı sistemine (binary) çevirip işlem yapıyor. Programlama yaparken binary olarak düşünmeli ve ona göre önlem almalısın. Benden bu kadar. Havlu atıyorum. Daha tecrübeli birileri daha iyi bir şekilde açıklar umarım. Kötü anlatımla vaktini çaldıysam kusura bakma.


Bu mesaja 1 cevap geldi.

Bu mesajda bahsedilenler: @girdap7
G
5 yıl
Yüzbaşı
Konu Sahibi

quote:

Orijinalden alıntı: Guest-06D4C1909

Sanırım anlatma becerim zayıf. Anlaşamadığımız nokta şu: Senin hata yok dediğin kısım onluk sayma (decimal) sayı sisteminde. Bilgisayar ise o işlemi ikilik sayı sistemine (binary) çevirip işlem yapıyor. Programlama yaparken binary olarak düşünmeli ve ona göre önlem almalısın. Benden bu kadar. Havlu atıyorum. Daha tecrübeli birileri daha iyi bir şekilde açıklar umarım. Kötü anlatımla vaktini çaldıysam kusura bakma.
Olur mu öyle şey söylediklerin gayet anlaşılabilir :)
Mantigima oturmayan bişey var onu çözmeye çalışıyorum. Neticede bu yazılımın verdiği sonuca göre matematiksel hesaplar ve sonuçlar elde edeceğiz. Bukadar basit bir dairenin ve cevresinin hesaplatilmasinda böyle bir sonuç aldığım için pythonda yapacagim bir hesaplamaya nasıl guvenebilirim. Neticede kusuratta olsa hesapta hata yapıyor. Bende bu hatayı nasıl asarım, nasıl doğru sonuç çıkmasını sağlarım, yazdığım kodda hatanin nerede olduğunun peşindeyim.

Bu işi dahada basite indirgeyelim

Print(2 * 3.14 * 10)

Bu kodu pythonda yazdığımda sonucun ne çıkması lazım ?

Benim ekranında çıkan sonuç aşağıdaki gibi ve ben bu sonucun neden böyle çıktığına anlam veremiyorum.


< Resime gitmek için tıklayın >





< Bu mesaj bu kişi tarafından değiştirildi girdap7 -- 14 Mayıs 2020; 9:18:48 >

< Bu ileti mobil sürüm kullanılarak atıldı >

R
5 yıl
Çavuş

Selamlar,

IEEE 754, Floating Point Arithmetic diye araştırabilirsiniz. Dilden bağımsız çok genel bir konu hocam. Herhangi bir hatanız yok. Buradan anlatarak anlaşılması zor bence.

Python dökümantasyonunda da buna özel bir sayfa var: https://docs.python.org/3/tutorial/floatingpoint.html


Bu mesaja 1 cevap geldi.
W
5 yıl
Yüzbaşı

böyle dene virgülden sonra sadece 2 rakam yazdırcak, 2 yerine 3 yazar isen 3.

x = round(5.76543, 2)
print(x)



G
5 yıl
Yüzbaşı
Konu Sahibi

quote:

Orijinalden alıntı: rashead

Selamlar,

IEEE 754, Floating Point Arithmetic diye araştırabilirsiniz. Dilden bağımsız çok genel bir konu hocam. Herhangi bir hatanız yok. Buradan anlatarak anlaşılması zor bence.

Python dökümantasyonunda da buna özel bir sayfa var: https://docs.python.org/3/tutorial/floatingpoint.html
Ben Şok !!!!!

Bir matematik mezunu olarak sabah sabah bildiklerimin hepsini sorgulattiniz bana :)
Kod yazdığımda yazacagima pişman oldum :)

Bilgisayarın bu kadar basit bir işlemde hatalı sonuç vereceğini hiç düşünmemiştim.

Bana aynı şeyi anlatmaya çalışan diğer arkadaslara da teşekkürler.

Peki bu standarttan kurtulmanın yolu yok mu. Basit bir hesap makinesi bile 2*3,14*10 işleminde doğru sonucu verirken benim yazacağım python kodunun da aynı sonucu vermesini nasıl sağlayacağım?

Yuvarlama veya belli bir basamağa kadar görüntüleme geçici bir çözüm olabilir. Gerçekten hassas hesaplamalarda virgülden sonra 20. Basamağın bile gerekli olduğu bir hesapta doğru sonucun çıkmasını nasıl sağlayacağız?



< Bu ileti mobil sürüm kullanılarak atıldı >

G
5 yıl
Yarbay

import decimal
r=decimal.Decimal( input("sayı"))
pi=decimal.Decimal('3.14')
çarpım=pi*r*2
print("cevap",çarpım)


Bu mesaja 1 cevap geldi.
G
5 yıl
Yüzbaşı
Konu Sahibi

quote:

Orijinalden alıntı: Gökşen PASLI

import decimal
r=decimal.Decimal( input("sayı"))
pi=decimal.Decimal('3.14')
çarpım=pi*r*2
print("cevap",çarpım)
Yardım için teşekkürler. Başlangıç seviyesini biraz aştık sanırım ama çok faydalı oldu.



< Bu ileti mobil sürüm kullanılarak atıldı >

L
5 yıl
Binbaşı

Bence çok saçma bir hata, neden çünkü:
< Resime gitmek için tıklayın >

Ben de deli oldum. Ve arkadaş şunu demek istiyor sanırım:
-"Tamam binary ve decimal olayından dolayı böyle oluyor ama r=3 alırsam olmuyor da neden sadece r=10 alınca oluyor?"

EDIT: Her şeye okeyim de bunun mantıklı bir açıklaması olamaz :)
< Resime gitmek için tıklayın >





< Bu mesaj bu kişi tarafından değiştirildi luck runs out -- 14 Mayıs 2020; 18:19:25 >

K
5 yıl
Yarbay

DH Mobil uygulaması ile devam edin. Mobil tarayıcınız ile mümkün olanların yanı sıra, birçok yeni ve faydalı özelliğe erişin. Gizle ve güncelleme çıkana kadar tekrar gösterme.