Keil'de double

Başlatan teapworm, 20 Mayıs 2014, 22:18:05

teapworm

arkadaşlar enteresan bi durumla karşılaştım bi yardım edin :)

gerekli şartlamaları yaptım.

if(134*0.707==87.668)
{
                GPIOD->ODR =0xF000;             
      bekleme(1);                         
      GPIOD->ODR =0x0000;             
      bekleme(1);                           
}

bu kodda bi sorun var çalışmıyor. STM32F4 discovery ile çalışıyorum. Normalde if doğru yani kitin üstündeki ledleri yakıp söndürmesi lazım ama olmuyor.

if ' in içeriğini 1.2*5 ==6 yapınca çalışıyor ama. Bi kaç tane float değerde daha aynı sorunla karşılaştım. Bi yardımcı alabilirseniz sevinirim.

Şimdiden teşekkürler...


Klein

134*0.707 = 94.738 eder.

if() şartında bizim  sabit olark gördüğümüz değerlerden en azından birinin değişken olduğunu varsayıyorum.


Klein

Siz daha önce yazdığınız için, tekrar etmek istemedim.   

MühendisAdayAdayı

Peki biz bu işlemleri yaptık karşılaştırma yapılmaz diyorsunuz çıktı değerini nerden görebilirim.

mufitsozen

#4
Alıntı yapılan: MühendisAdayAdayı - 21 Mayıs 2014, 00:38:36
Peki biz bu işlemleri yaptık karşılaştırma yapılmaz diyorsunuz çıktı değerini nerden görebilirim.

@gerbay
Alıntı Yapepsilon komşuluğunda olup olmadığına bakmanız lazım..
demis

sizde bunu soyle test edebilirsiniz:

if (abs(x-94.738)<epsilon){
......
}
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

hasankara

aralık kontrolü yapın en azından gerbay hocam haklı bu konuda çünkü.

if(101.808 > 134*0.707 && 134*0.707 > 87.668)
{
      GPIOD->ODR =0xF000;              
      bekleme(1);                          
      GPIOD->ODR =0x0000;              
      bekleme(1);                           
}

learner

Keilde sıklıkla karşılaştığım bir problemde, if sorgusu içerisinde matematik işlemleri doğru çalışmaması. İf den önce hesaplayıp karşılaştırıyorum. Böyle problem yaşayan oluyor mu?

SpeedyX

if(degisken == 94.73) --> çalışmaz

float degisken = 134.0*0.707;
if(degisken == 134.0*0.707)
Şeklinde karşılaştırma 3-4 derleyicide sorun çıkarmadı. Yani değerin sonucunu direkt yazmak yerine derleyiciye hesaplatırsak sorun çıkmayabiliyor ama kesin bir yöntem değil. Her zaman çok ufak farklar olabilir ve eşitlik sağlanmaz.

mufitsozen

#8
Alıntı yapılan: gerbay - 21 Mayıs 2014, 09:37:50
arkadaşlar bunun Keil ile ilgisi yok. Bu genel olarak böyle. Kayan noktalı sayılar için IEEE-754 diye bir standart var. Doğru düzgün derleyiciler kayan noktalı sayıları bu standartta anlatıldığı gibi tanımlar ve kullanır.

sizin kod içerisine yazdığınız bir ondalıklı değer FPU registerlarında çoğu zaman sizin yazdığınız gibi tutulmaz. Gerçek olmamakla birlikte sırf olayı anlatmak için örnekliyorum;  diyelimki siz 2.3 yazdınız kodun içine, bu sayı FPU registerında 2.9999999999 gibi bir değer olarak tutulabiliyor (bunu denemeyin olayı anlatmaya çalışıyorum). Bu gösterimsel ve içerdeki registerda değişen durumlardan dolayı ondalıklı sayılarda eşitlik kontrolü yapılmaz.

tekrar yazıyorum, bu sadece keil için geçerli değil, genel kural..

yok ya!

ben karakoyden 5 liraya aldigim calculatorde 2.3 yazinca 2.3 oluyor siz niye 2.9999999.. oluyor diyorsunuz
bu iki sayinin arasinda 0.69999999.. fark var yav
bu IEEE bu kadar hatalimi
bunlar bir komplo sabotaji ile bizim bilisayarcilarin kafasinimi karistirmak istiyor. Hem niye 2.3 icerde 2.9999999... diye tutulur diye bir mayis sabahi yaziyorsunuz.... coook manidar buluyorum bunu. Birde cavap olarak sehven yapmisim ozur dilerim demeyin sayin @gerbay, yakalndiniz cilaniz dokuldu foyaniz ortaya cikti...


bugun 21 mayis 2014 mufit sozen sanada hayirli gunler diler sevgili @gerbay. sen cok yasa!! canimsin...


mesaj birleştirme:: 21 Mayıs 2014, 09:57:05

Alıntı yapılan: SpeedyX - 21 Mayıs 2014, 09:52:49
if(degisken == 94.73) --> çalışmaz

float degisken = 134.0*0.707;
if(degisken == 134.0*0.707)
Şeklinde karşılaştırma 3-4 derleyicide sorun çıkarmadı. Yani değerin sonucunu direkt yazmak yerine derleyiciye hesaplatırsak sorun çıkmayabiliyor ama kesin bir yöntem değil. Her zaman çok ufak farklar olabilir ve eşitlik sağlanmaz.

hocam bu genellikle optimizasyonlar vb den dolayi oyle oluyordur Derleme asamasinda sabit bir sayi karsilastirildigi icin oyle oluyor. Denemek icin birde butun optimizsayonlari kapasaniz? (bence o sabit sayilarin karsilastirildigi if icin if kodu bile uretilmiyordur. Hadi sayin @gerbay su assembler listingini gorelim optimizasyonla derlenmis iki degisik kod icin....

Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

learner

Ben okurken yanlış olduğunu fark etmedim :D 2.299999999 gibi algıladım.

SpeedyX

Debug ekranı resmini vereyim, eşitlik sağlanıyor. ASM kodlarını da inceleyebilirsiniz.

_CmpEq32f adında bir alt fonksiyon çağırıyor. O da FLT_EQ adlı bir alt rutine gidiyor. jne lerle karşılaştırıyor. Birebir eşitler, epsilon yaklaşımı yapmıyor diye düşünüyorum.





Fakat burada gösterdiğim önerilmez, float değerleri direkt karşılaştırmayınız.

SpeedyX

Deneyelim, derleyiciyi float karşılaştırma yapmaya nasıl zorlayabiliriz?

mufitsozen

mesela 134*0.707 = 94.738 

134 yerine 134f
0.707 yerine 0.707f
94.738 yerine 94.738f

yazarak deneyelim, yani butun floating degerleri double yerine float yapalim
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

SpeedyX

float degisken = 134.0f*0.707f;
if(degisken == 134.0f*0.707f)
{
  degisken++;
}

Fark yok, herşey aynı.

float degisken = 134.0f*0.707f;
if(degisken == 94.738f)
{
  degisken++;
}

Fark yok, herşey aynı.

94.738f değerini 9.47379989E+1 olarak görüyor.

Neyse konu anlaşılmıştır.

mufitsozen

Alıntı yapılan: SpeedyX - 21 Mayıs 2014, 11:55:10
float degisken = 134.0f*0.707f;
if(degisken == 134.0f*0.707f)
{
  degisken++;
}

Fark yok, herşey aynı.

float degisken = 134.0f*0.707f;
if(degisken == 94.738f)
{
  degisken++;
}

Fark yok, herşey aynı.

94.738f değerini 9.47379989E+1 olarak görüyor.

Neyse konu anlaşılmıştır.

hocam bu degerler icin yapilan islemde kayip olmuyordur.

Onun yerine binary olarak gosterilemeyen bir sayi ile baslayin ornegin 0.1f
bunu kendisi ile 1000 kere toplayin (1000f ile carpmis gibi) sonucun 100f olmayacagini gosterin!

mesela
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.