Float sayılarda pik oluşur mu?

Başlatan mistek, 16 Mart 2014, 14:46:12

mistek

Birkaç haftadır kullandığım işlemcide yazılım sıkıntısı yaşıyorum. (Stm32f100)

Float sayılarla 4 işlem yapıp kendi aralarında karşılaştırıyorum.

Örnek:
Dizi elemanlarım en büyük değer: 8.123 (A)
Çarpan en büyük değer: 1.23 (B)
Bölen en küçük değer: 1.1 (C)
Sonuç (D)

Sonucun en büyük değeri gerçek hayatta atıyorum 15.83 oluyor.

D= (A*B) / C;
İşlemciye bu işlemi yaptırıyorum sonra diyorum ki
D eğer 20 den büyükse bana uyarı ver. Aynı zamanda da hep sonucun en büyük değerini tutuyorum gözlüyorum.
Bu işlemi 1 gün boyunca yaptırdığımda 2 veya 3 kez saçma sapan değerler dönüyor 15.83 olması gerekirken 40-50 gibi bişey oluyor.
Hatalı sonuçların hiçbir periyodikliği yok birbiri ile ilişkiside yok.

Veri tiplerini doğru tanımladım.

İşlemci hata yapmıyordur da Float sayılarla çalışırken dikkat etmem gereken nokta nedir?
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

mehmet

Eşitlikten ziyade büyük ve küçük olduklarını kontrol
ediniz. Virgülden sonra hassasiyet fazla olduğu için
eşitlik bulmanız çok zor...
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"

mistek

Evet hocam eşitlik kullanmıyorum büyük mü küçük mü ona bakıyorum.
Asıl mesele, virgülden sonra hata olmasını beklerim ama sayının bütünüyle yanlış olmasını anlayamadım.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

muhittin_kaplan

hocam  hepsini aynı satırda yapmaktansa ayrı ayrı satırlarda yapıp takip ediniz

z=a*b
D=z/C gibi

mistek

Birde öyle deniyeyim hocam, hangi işlemde sonucun bozulduğunu tespit edebilirim belki.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

mufitsozen

Alıntı yapılan: gerbay - 16 Mart 2014, 20:48:24
kod yokmu kod? kodsuz bir şey söylenemez..

vayyt hinzir @gerbay, vay!

tabii bi tek uyanik sensin dimi programa bakacam bahanesi ile programi calacan dimi!  :P

seni taniyoozz artik!  ;D

aslinda anlatilanlara bakilirsa kullanilan formullerde integer/float mixed islemler yapiliyordur. Bu yuzdende bazi ara hesaplamalarda integer/float donusumlerinden dolayi yanlis hesaplamalar oluyordur. 
bu konuda daha once 137bin 476 kere konusulmustur, picprojede vede hatta butun dunyada.

cozum nedir?
cevabi basit arkadaslar gomulu program yazacaksaniz fixed-point matematik kullanmayi ogrenin.

gomulu sistemlerde float kullanmadan once 2, 3 hatta 5 yok yok 10 kere dusunun! :-[
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

mistek

#6
Alıntı yapılan: gerbay - 16 Mart 2014, 20:48:24
kod yokmu kod? kodsuz bir şey söylenemez..

Hocam istediğiniz kod olsun :D

#include "stm32f10x.h"

#define ADC_CEVIR    0.0008056640625
#define GERILIM_BOLUCU  18.4358  

float Volt=0.0;


float enyuksektutucu(void);

int main(void)
{


while(1)
{
     Volt = (float) Volt_Oku() * ADC_CEVIR * GERILIM_BOLUCU; //Volt oku fonksiyonu geriye sadece ADC kanalı değerini döndürür. Max 4095

     if( 60.0 < Voltaj)
          Led_Yak;

     printf("V=%0.2f",enyuksektutucu()); //En fazla geleceği değer 60-61 olması lazım ama ekrana 70-80 gibi bir değer yazdırıyor.
}
}

float enyuksektutucu(void)
{
	static float oncekivoltaj=0;
	static float suankivoltaj=0;
	static float enyuksek=0;
	
	suankivoltaj = Volt;
	
	if( oncekivoltaj < suankivoltaj )
	{
		oncekivoltaj = suankivoltaj;
		enyuksek = oncekivoltaj;
	}
	
	return enyuksek;
}


@mufitsozen hocam daha önce problemle karşılaşmadığım için float kullanıyordum eğerki arada böyle sapıtması söz konusu ise ona göre tedbir almakta fayda var.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

mistek

#7
Hocam o fonksiyon basit DMA nın ADC datasını yazdığı sayıyı geri döndürüyor.

uint16_t Volt_ADC=0;

int16_t Volt_Oku(void)
{
   return Volt_ADC;
}

Karışık olmasın diye eklemedim ADC ve DMA ayarlarınıda koyabilirim isterseniz?

Birde buraya yazarken farkettim. Volt_ADC değişkeni unsigned tanımlamışım ancak fonksiyon geri döndürürken int16 yapıyor bu arada bozulma olur mu? Nasıl gözümden kaçtı acaba  :o

Ya da bir ihtimal DMA ilgili registera yazma yaparken bende o sırada okuma yapıyorsam data bozuluyor olabilir mi?
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

mufitsozen

#8
Alıntı yapılan: mistek - 16 Mart 2014, 21:53:56
Hocam istediğiniz kod olsun :D

#include "stm32f10x.h"

#define ADC_CEVIR    0.0008056640625
#define GERILIM_BOLUCU  18.4358  

float Volt=0.0;


float enyuksektutucu(void);

int main(void)
{


while(1)
{
     Volt = (float) Volt_Oku() * ADC_CEVIR * GERILIM_BOLUCU; //Volt oku fonksiyonu geriye sadece ADC kanalı değerini döndürür. Max 4095

     if( 60.0 < Voltaj)
          Led_Yak;

     printf("V=%0.2f",enyuksektutucu()); //En fazla geleceği değer 60-61 olması lazım ama ekrana 70-80 gibi bir değer yazdırıyor.
}
}

float enyuksektutucu(void)
{
	static float oncekivoltaj=0;
	static float suankivoltaj=0;
	static float enyuksek=0;
	
	suankivoltaj = Volt;
	
	if( oncekivoltaj < suankivoltaj )
	{
		oncekivoltaj = suankivoltaj;
		enyuksek = oncekivoltaj;
	}
	
	return enyuksek;
}


@mufitsozen hocam daha önce problemle karşılaşmadığım için float kullanıyordum eğerki arada böyle sapıtması söz konusu ise ona göre tedbir almakta fayda var.

hocam benim ilk gozlemim sizin kullandiginiz compiler cok akilli bence Voltaj ve Led_Yak icin "not declared" demesi lazim. Sizin kod hem compile ediyor, yukleniyor vede kosarken 60dan fazla filan birseyler buluyor kendi basina. :P

saskinim vallahi! :o :o

mesaj birleştirme:: 16 Mart 2014, 23:08:48

bu arada gerbay bir cevap yazmis bile.

sizin hatayi veren kodu değilde ondan sizin yaptiginiz ozetleri vermeniz yuzunden iki kisinin vaktini bosa harcadiniz bile. Yani sikayet icin değil, valla hakkimiz helal olsun ama sevkimiz kiriliyor. boyle mesajlari onemsememeye, gormezden gelmemeye basliyoruz.

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

mistek

@mufitsozen hocam

Kodun tamamını koymamamın sebebi 10-15 sayfa civarında oldu ve karman çorman yazılım yaptığım için çok karışık olacak diye bende özetleyerek en muhtemel kısmı koymayı uygun gördüm. Sizin açınızdan bakınca evet ortada kod yok bişey yok ucu açık bir soru sormuşum gibi gözüküyor söylediklerinizde çok haklısınız biraz benim tez canlılığımdan kaynaklanıyor özür diliyorum. Siz böyle yazınca kendimi kötü hissettim.

/*********************************************/

Aslında sorum şuydu koddan bağımsız olarak float sayılarda pik oluşur mu oluşmaz mı? Yani ihtimalde olsa böyle bişey varmı onu bilmek istemiştim.

@gerbay hocam yine kodu çalamadınız ::)

boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

t2

#10
ADCyi fazla hassas ayarlayınca böyle sorun çıkabiliyor. Bit derinliğini azaltalım. Misal 12 bit fazladır. 10 bit neyinize yetmiyor.

Ben de picle uğraşırken bu durumu gördüm. Hesap kitap yapıyorum . Pis işlemci, itinayla  ölçtüğüm sonucları mahfetmiş, bozmuş. tükaka..

mistek

Çözünürlüğü nasıl değiştiriyorsunuz hocam? (Stm32f100 ve Keil kullanıyorum.)
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

z

12 Bitin tamamini degil de kac tane istiyorsan soldan o kadar bit al.

Yani;

Sonuc=ADC_Val>>(12-Cozunurluk);

8 bit cozunurluk istiyorsan

Sonuc=ADC_Val>>4;

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

mistek

Alıntı yapılan: z - 18 Mart 2014, 00:22:04
12 Bitin tamamini değil de kac tane istiyorsan soldan o kadar bit al.

Yani;

Sonuc=ADC_Val>>(12-Cozunurluk);

8 bit cozunurluk istiyorsan

Sonuc=ADC_Val>>4;
Sağolun hocam yazılımsal düşünemedim.

@t2'nin yazdıklarında kafam bi an donanımsal olarak nasıl oluyor tarafına gitti.

boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

muuzoo

#14
Bir sorun da şu olabilir float sayılarla
#define ADC_CEVIR    0.0008056640625


Bu sayıyı ifade edemezsiniz. Single Precision Float Sayılarda belirttiğiniz sayı : 8.0566405e-4 haline geliyor. Bu da biriken bir hataya sebep olabilir. Float sayılarda hassasiyet kavramı ayrı bir dünya. Çok ufak sayılarla uğraşmıyorsanız çoğunlukla farkına varmazsınız ama sınırlarda dolaşmaya başlayınca önemli hale geliyor.
gunluk.muuzoo.gen.tr - Kişisel karalamalarım...