Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => ARM => Konuyu başlatan: teapworm - 20 Mayıs 2014, 22:18:05

Başlık: Keil'de double
Gönderen: teapworm - 20 Mayıs 2014, 22:18:05
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...

Başlık: Ynt: Keil'de double
Gönderen: Klein - 20 Mayıs 2014, 22:36:26
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.

Başlık: Ynt: Keil'de double
Gönderen: Klein - 20 Mayıs 2014, 23:55:52
Siz daha önce yazdığınız için, tekrar etmek istemedim.   
Başlık: Ynt: Keil'de double
Gönderen: 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.
Başlık: Ynt: Keil'de double
Gönderen: mufitsozen - 21 Mayıs 2014, 01:01:16
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){
......
}

Başlık: Ynt: Keil'de double
Gönderen: hasankara - 21 Mayıs 2014, 01:06:17
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);                           
}
Başlık: Ynt: Keil'de double
Gönderen: learner - 21 Mayıs 2014, 08:52:12
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?
Başlık: Ynt: Keil'de double
Gönderen: 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.
Başlık: Ynt: Keil'de double
Gönderen: mufitsozen - 21 Mayıs 2014, 09:53:49
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....

Başlık: Ynt: Keil'de double
Gönderen: learner - 21 Mayıs 2014, 09:59:40
Ben okurken yanlış olduğunu fark etmedim :D 2.299999999 gibi algıladım.
Başlık: Ynt: Keil'de double
Gönderen: SpeedyX - 21 Mayıs 2014, 10:33:36
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.
Başlık: Ynt: Keil'de double
Gönderen: SpeedyX - 21 Mayıs 2014, 10:54:09
Deneyelim, derleyiciyi float karşılaştırma yapmaya nasıl zorlayabiliriz?
Başlık: Ynt: Keil'de double
Gönderen: mufitsozen - 21 Mayıs 2014, 11:01:31
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
Başlık: Ynt: Keil'de double
Gönderen: 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.
Başlık: Ynt: Keil'de double
Gönderen: mufitsozen - 21 Mayıs 2014, 11:59:58
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
Başlık: Ynt: Keil'de double
Gönderen: SpeedyX - 21 Mayıs 2014, 12:10:31
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.
Başlık: Ynt: Keil'de double
Gönderen: speak48 - 31 Mayıs 2014, 12:28:47
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