STM32F407 işlemci ile aşağıda ki debug görüntüsünü verdiğim sorunla karşılaştım. Virgülden sonraki sayılara dikkat ederseniz hatayı anlayacaksınız. Daha önce karşılaşan var mı? Yardımlarınızı bekliyorum.
(https://i.ibb.co/Q6Ldngw/float.png) (https://ibb.co/Q6Ldngw)
O gördüğün durum kayan noktalı sayıların özelliğidir. Reel sayıların çok büyük bir bölümünün eksiksiz bir kayan nokta eşdeğeri yoktur.
Mesela float 10'u float 3'e bölersen, sonucu da tekrar 3 ile çarparsan 10 elde etmezsin, ama 10'a çok yakın bir rakam elde edersin. Oradaki sapma senin işlemin sonucunu etkileyecek kadar önemli ise, "float" yerine "double" kullanabilirsin. Ama gene 10'u 3'e bölüp sonucu 3 ile çarparsan 10 elde etmezsin.
Marsa birseyler gondermiyorsan cokda sorun degil :D
Degiskeni double olarak degitirebilirsin veya derleyicinin FPU yu kullanip kullanmadiginada bakabilirsin.
Simdi aklima geldi belki bunu IDE yorumlarken yanlis yorumluyordur.
x86_64 mimarisinde GCC matematik kütüphanesi bütün işlemleri maksimum çözünürlükte yapar (double'dan daha iyi bir çözünürlük), sonra da çıkan sonucu, ilgili tip ile (float veya double) temsil edilebilen en yakın değere yuvarlar. O yüzden mesela ben şimdi masaüstü bilgisayarda basit bir C programı ile bunu denesem bu problemi görmem. Ama eğer kullanılan gömülü işlemcinin matematik kütüphanesi bu tarz bir yuvarlama yapmıyorsa böyle sapmalar hep olur.
Bir ekleme yapayım, bu yüzden float sayılar ile karşılaştırma yaparken dikkatli olmak lazım özellikle "==" kontrolü için.
Alıntı yapılan: saban88 - 08 Ekim 2019, 17:29:44STM32F407 işlemci ile aşağıda ki debug görüntüsünü verdiğim sorunla karşılaştım. Virgülden sonraki sayılara dikkat ederseniz hatayı anlayacaksınız. Daha önce karşılaşan var mı? Yardımlarınızı bekliyorum.
Ahh nostalji!
Sene 1974 Fortran IV dersinde ikinci odevimizi hazirliyoruz, ODTUdeki IBM 360/40 bilgisayarda, Bu durumdan dolayi bir suru vakit kaybetmistik.
neden 0.1(onluk sistem) binary de sonsuz dizi gibi cikar ve (X/0.1)*0.1 niye hicbir zaman X'e esit olmuyor vs gormustuk.
45 sene gecmis ustunden! :)
why 0.1 does not exist in floating point (https://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/)
@saban88 https://ibb.co/jM816rH
senin islemci biraz dandikmis sanki hee :D :D
floating kütüphanelerini karşılaştırmak lazım bununla...
@saban88 hocam makine ondalıklı sayı bilmez, onun bildiği ikilik sistemdir. senin kullandığın ondalıklı sayılar aslında bir şekilde ikilik sistemde tutuluyor. bütün sayıları tutacak yer olmadığı için arada eksik kalan kısımlar var. olayın özü bu.
https://www.wikiwand.com/en/Single-precision_floating-point_format
burdan başla okumaya anlarsın mevzuyu.
@Erol YILMAZ Bunu hw hesapladi sw degil. ;)
Alıntı yapılan: OptimusPrime - 10 Ekim 2019, 17:01:55@saban88
https://ibb.co/jM816rH
senin islemci biraz dandikmis sanki hee :D :D
stm32f4 den bahsediyoruz o kadarda olmas gerk. Arduinoda olmayan hata bunda oluyor.
bilgilerndirmeler için teşekkürler.Ben bu tarz sorunla karşılaşacağımı hiç tahmin etmezdim. Enteresan geldi. Çözüm denemelerimi sizlerle paylaşmak isterim.
-IDE değiştirdim truestudie dan keile geçtim birşey değişmedi.
-Float yerine double kullandım biraz daha yakın sonuç vermeye başladı.
-Forumlarda bu tarz sorunlarla karşılaşanların tartışmalarını okudum. Sorunun işlemci kaynaklı olduğu kanaatine vardım ama 32 bit m4 işlemcinin böyle bir sorun vereceğini hiç düşünmezdim.Daha önce pic de ve arduinoda hiç böyle birşeyle karşılaşmadım.
-Problem aslında ekran da bu sayıları göstermekti.Çünkü bir sayıyı kullanıcı 1.80 diye kaydettikten sonra sistem bunu ona 1.79 şeklinde gösteriyordu. Buda kullanıcı tarafından istenilmiyordu. Bende bunun için bir fonksiyon yazarak bir nevi kullanıcıya istediği şeyi gösterdim. :)
-Hesapta vereceği milyonda birlik hataya gelince zaten analog veri okuyup hesaplama yapacağı için analog verideki okuma hatasına oranla çok daha küçük bir hata olacağından kimse fark etmeyecektir diye düşünüyorum.
-fpu yu harware yada software yapmam birşeyi değiştirmedi.
Double dogrudan fpu yu devre disi birakir. Ben derleyicinin fpu yu kullandigini dusunmuyorum. Dogrudan asm yide kontrol edebilirsin emin olmak icin. Asagidaki linke de goz at derim. ::ok
https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/10-useful-tips-to-using-the-floating-point-unit-on-the-arm-cortex--m4-processor
Alıntı yapılan: saban88 - 11 Ekim 2019, 11:22:25Daha önce pic de ve arduinoda hiç böyle birşeyle karşılaşmadım.
Pic de hangi derleyici ile karşılaşmadınız merak ettim. CCS C derleyicede aynı olay var çünkü.
Alıntı yapılan: fahri- - 14 Ekim 2019, 09:42:55Pic de hangi derleyici ile karşılaşmadınız merak ettim. CCS C derleyicede aynı olay var çünkü.
pic de ilk başlarda pic basic pro kullanıyordum sonradan ccs c ye geçtim ccs c de float ile çok uğraşmamış olabilirim hatırlamıyorum. pic basic pro da zaten float yok.
Alıntı yapılan: OptimusPrime - 14 Ekim 2019, 05:54:34Double dogrudan fpu yu devre disi birakir. Ben derleyicinin fpu yu kullandigini dusunmuyorum. Dogrudan asm yide kontrol edebilirsin emin olmak icin. Asagidaki linke de goz at derim. ::ok
https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/10-useful-tips-to-using-the-floating-point-unit-on-the-arm-cortex--m4-processor
Hocam M7 mcuların bazılarında (üst segment) double precision fpu var. Acaba bu durumda fpu işlerde double türü kullanıyor olabilir mi?
Bir de m7 de gördüm de m4 de var mı bilmiyorum. fpuda yuvarlama özelliği var. saturation diye geçiyordu sanırım. Ben o konuyu bu tarz küsüratları otomatik yuvarlama olarak algıladım. Acaba yanılıyor muyum?
Saturation yuvarlamadan ayri bir sey.
8 bit isaretli sayilar icin konusursak;
8 bitde en buyuk pozitif sayi +127 dir.
Eger 127 ile 2'yi toplarsan sonuc 129 eder ve 129 verisi -127 demektir.
Halbuki pozitif iki sayinin toplami negatif edemez. Yukaridaki ornekte overflow durumu olmustur.
Eger matematik rutinlerin bu gibi durumlara dikkat etmezse cok vahim hatalar olur.
Saturation ozelligi aktif edilirse 127+2=127 olur. Yani veri sinirlanir. Bu durumda da sistem hata yapar ama sonuc vahim olmaz.
Aynen 12v ile beslenen opampli devrenin kazanci 10 iken girise 2v girildiginde cikis nasil 20v degil de 12v oluyorsa saturation durumunu dikkate alan rutinler de + ve - yondeki tasma durumlarinda sonuc, bu degerlerden birisine yaslanir.
Alıntı yapılan: z - 15 Ekim 2019, 12:55:30Saturation yuvarlamadan ayri bir sey.
8 bit isaretli sayilar icin konusursak;
8 bitde en buyuk pozitif sayi +127 dir.
Eger 127 ile 2'yi toplarsan sonuc 129 eder ve 129 verisi -127 demektir.
Halbuki pozitif iki sayinin toplami negatif edemez. Yukaridaki ornekte overflow durumu olmustur.
Eger matematik rutinlerin bu gibi durumlara dikkat etmezse cok vahim hatalar olur.
Saturation ozelligi aktif edilirse 127+2=127 olur. Yani veri sinirlanir. Bu durumda da sistem hata yapar ama sonuc vahim olmaz.
Aynen 12v ile beslenen opampli devrenin kazanci 10 iken girise 2v girildiginde cikis nasil 20v degil de 12v oluyorsa saturation durumunu dikkate alan rutinler de + ve - yondeki tasma durumlarinda sonuc, bu degerlerden birisine yaslanir.
Tamamdır. Ayrıca rounding varmış. İyi oldu abi söylediğin.
Double precision fpu double degiskene delalet eder :)
Ama yinede C kodunun ASM olarak ne urettigine ve derleyicinin fpu yu kullanmasina nasil zorlanabilecegine goz atilmasinda fayda var. ;)