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...
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.
Siz daha önce yazdığınız için, tekrar etmek istemedim.
Peki biz bu işlemleri yaptık karşılaştırma yapılmaz diyorsunuz çıktı değerini nerden görebilirim.
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){
......
}
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);
}
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?
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.
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....
Ben okurken yanlış olduğunu fark etmedim :D 2.299999999 gibi algıladım.
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.
(http://i.hizliresim.com/7ma5yW.png)
(http://i.hizliresim.com/jJgm6n.png)
Fakat burada gösterdiğim önerilmez, float değerleri direkt karşılaştırmayınız.
Deneyelim, derleyiciyi float karşılaştırma yapmaya nasıl zorlayabiliriz?
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
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.
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
Hocam kendisiyle derken 0.1f ile demek istediniz sanırım, kendisiyle toplarsam (degisken += degisken) sayı 100 olmaz zaten.
float degisken = 0.1f;
uint16_t i;
for(i=0;i<1000;i++)
{
degisken += 0.1f;
}
if(degisken == 100.0f)
{
degisken++;
}
degisken = 1.00099044E+2 bulunuyor ve eşitlik sağlanmıyor.
-----------------------------------
degisken = 0.1f;
degisken *= 1000.0f;
if(degisken == 100.0f)
{
degisken++;
}
Burada sorun yok, eşitlik sağlanıyor.
Görüldüğü üzere direkt karşılaştırmaya güven olmaz.
floating point sayı 2 nin tam katı değilse
hiçbir zaman kullanığınız sayı sayının tam kendisi değildir.
lakin print falan ederken sayının aynısıymış gibi yuvarlama yapar
eşitlik olayınıda önce string çevirip stringleri aynımı diye karşılaştırmak daha güvenilir olabilir.
ama siz floata güvenmeyin gene