Hayret dogrusu ,
arkadaslar USB den gelen paket dizisinin ilk elemanini
#define data paket[0]
int8 paket[64];
long sayi;
sayi=10*data+540;
yapip LCD'ye yazdirioyum.
printf(lcd_putc,"\Sonuc: %ld",sayi);
Sorunum su LCD'de bazen hatali sonuclar cikiyor.Örnegin gelen veri 100 oldugunda(bundan eminim cünkü gelen veriyide LCD gösteriyorum ...)
10*75+540=1290 cikmasi gerekirken 772 gibi sonuc cikiyor.
Bu sonuc nerden kaynaklaniyor , hatam nerde?
Ha birde gelen verilerin tutuldugu int8 paket[64];
dizisini long paket[64];
tipinde tanimladigim zamanda pic donuyor islem yapmiyor....
Not:USB'den veri byte olarak geliyor bunuda hatirlatayim.
Acaba sorun gelen verinin tipindenmi,
yoksa yaptigim hesaplamadanmi yoksa LCD'den mi kaynaklaniyor?
(772-540)10=23,2
data 23,2 enteresan...
sorunu cözdüm arkadaslar
tek satir'da nedense yanlis hesap yapiyor pic.
yani söyle olunca hatali sonuc cikiyor.
sayi=10*data+540;
bende söyle yaptim bu sefer oldu.
sayi=data*10;
sayi=sayi+540;
hayret neden tek satirlik kodda dogru hesap yapmadi anlayamadim...??
Büyük ihtimalle derleyici işlem sırasını karıştırıyordur. :)
Şöyle dene mesela
sayi=(10*data)+540;
her seferınde 772 vermsı enteresan,
10* (data +540) buda cevabı vermıyor baska bır ıs var ama cozemedım...
Alıntı yapılan: senerenemre - 12 Ocak 2011, 21:18:10
her seferınde 772 vermsı enteresan,
10* (data +540) buda cevabı vermıyor baska bır ıs var ama cozemedım...
dostum sende mi denedin?
Sendede mi aynisi olyuor?
Hayret edilecek birsey...
Bende de aynı tür problemler oluyordu. Sizin gibi bende işlemleri basitleştirip adımları çoğalttığımda doğru sonuca ulaşabiliyordum. ;) Ama sebebini bilmiyorum.
Hayret o zaman bu CCS Compilerein bir BUG'u olsa gerek..
Alıntı yapılan: Digimensch - 12 Ocak 2011, 19:38:16
sorunu cözdüm arkadaslar
tek satir'da nedense yanlis hesap yapiyor pic.
yani söyle olunca hatali sonuc cikiyor.
sayi=10*data+540;
bende söyle yaptim bu sefer oldu.
sayi=data*10;
sayi=sayi+540;
hayret neden tek satirlik kodda dogru hesap yapmadi anlayamadim...??
Kodunuzda data 8 bitlik bir değişken. Dolayısıyla data=100 için "10*data" ifadesinin sonucu 8 bitlik bir ara değişkende saklanacağından 232 (10*100 - 3*256) olacaktır. 540 + 232 = 772. Görüldüğü üzere matematiksel işlemde bir hata yok. O halde hata nerede?
Derleyiciler matematiksel işlem yaparken önce tüm değişkenleri, işleme tabi tutulacak değişkenlerden boyutça büyük değişkenin türüne dönüşüm yaparlar. CCS C derleyicisinde varsayılan tamsayı türü diğer derleyicilerde olduğu gibi
inttir; fakat ANSI C uyumlu derleyicilerden farklı olarak boyutu 8 bittir. Bu yüzden 10 * data ifadesinde 10, 8 bitlik bir değişken olarak değerlendirilecektir.Oysa Hitech PICC ve C18 derleyicilerinde 16 bitlik değişken kullanılarak işlem sonucu hesaplanacaktı. Bu durum CCS C de bu tür bir bug olduğu anlamına gelmez.
Doğru ifade,
sayi= (long)data*10 + 540;
Bak bu byte mevzu gözümden kaçmış iyi yakalamışsın @tmcone.
Öyleyse derleyicinin aslinda
sayi= data*10 + 540;
seklinde bir kullanimda data byte oldugu icin hata yok ama yinede dikkatli ol diye bir uyari falan vermesi gerekmiyormu?
Alıntı yapılan: Digimensch - 13 Ocak 2011, 01:07:45
Öyleyse derleyicinin aslinda
sayi= data*10 + 540;
seklinde bir kullanimda data byte oldugu icin hata yok ama yinede dikkatli oldu diye bir uyari falan vermesi gerekmiyormu?
aynı olayı c# da yapsaydık hata verir derlemezdi... ama ccs derliyor
byte a = 10;
ushort b = a * 10 + 540;
Cannot implicitly convert type 'int' to 'ushort'. An explicit conversion exists (are you missing a cast?)
byte a = 10;
ushort b = (ushort) (a * 10 + 540);
bilinçli tür dönüşümü
çünkü c#da işlem hesaplamaları int(32bit signed integer) e göre yapılıyor ve ushort(16bit unsigned integer) aralığı sonucu kapsayamıyor, sonucu almak için bilinçli tür dönüşümü yapmak gerekiyor. ccs de ise tmcone'un da değindiği gibi 8 bite göre yapılıyor ve programcının bunu bilerek matematiksel işlemler yapacağını varsayıyor olacak ki bir uyarı yada hata belirtmiyor; kısaca ccs bize kullandığınız derleyiciyi iyi tanıyın mesajı veriyor. :)
Ama dikkat ederseniz ilk mesajimda
gelen veri byte tipinde ok .
ama su sekilde
#define data paket[0]
int8 paket[64];
yaptigim icin gelen veri int8 tipndeki dizinin bir elemani artik.Öyleyse tip'de int8 olmus olmuyormu??
Simdi ben aynen söyle yaptigimda
int8 sayi;
sayi=10*data+540;
seklinde yaptigimda olmasi gerekmiyormu? ama olmuyor
ve nitekim simdi denedim
sayi=((long)data*10)+540; >>>> sonuc hatali
sayi int8 tipinde oldugu icin
sayi=((int8)data*10)+540; >>>>>sonuc yine hatali
su sekilde yapinca
sayi=data*4;
sayi=sayi+600; >>>>>> sonuc dogru cikiyor !!!
bende birşeyler denedim :
int x;
long y;
iken,
bilinçsiz dönüşüm :
x = 100;
y = ((long)x * 10) + 540;
printf(lcd_putc,"%ld",y);
yapınca, lcd de gördüğüm sonuç: 1540 = doğru
bilinçli dönüşüm :
y = 100;
x = ((int)y * 2) + 55;
printf(lcd_putc,"%u",x);
yapınca, lcd de gördüğüm sonuç: 255 = doğru
"int" yerine "int8" ; "long" yerine "int16" yazmak da olması gerektiği gibi sonucu etkilemiyor...
bilinçli dönüşümde y değişkenini 2 ile değilde 3 ile çarpsak ne olurdu ? sonuç 355 olurdu, oysa x değişkeni byte olduğundan 0-255 (256) değer alabilir, o yüzden sonuç, 355 mod 256 = 99 çıkar/çıkıyor...
yani int 128
unsigned int 255'e kadar saniyorum byte 127'ye kadar deger alabiliyor degilmi Hocam??
Bunlarin alabilecekleri maximum degerleri bilmekte fayda var !!!
tesekkürler
int veri tipinin alabileceği en büyük değer 255 değildir. -127 +128 arası değer alır. Tabi bu aralık derleyiciye göre farkeder.
BYTE, unsigned int, char, ... gibi veri tipleri 0..255 değeri alır.