Ynt: degisken sorusu

Başlatan Karamel, 02 Eylül 2015, 14:58:02

Karamel

merhaba. esrarengiz gorunen bir sorun ile karsilatim. rtc unit i calistirinca. onu usb den set edeyim dedim ama asagidaki sorun bu yapmama engel oluyor.

time unsigned long olarak tanimli bir degisken.
ss1 ss2 dk1 dk2 sn1 sn2 ise unsigned char. usb den bilgileri char olarak gonderiyorum. kirmizi olan kisim ya hic olmazsa. yada saatin basi ornegin 07:45:29 gibi sifir ile basliyorsa sorun olmuyor. ama bu degisken char 0 dan farkli mesela 1 olursa. sorun cikartiyor.

time = (3600 *  ((ss1-48)*10 +(ss2-48))) + (60 * (((dk1-48)*10) + (dk2-48)) ) + (((sn1-48)*10) + (sn2-48));


kirmizi kismi silip. asagidakini yazdigimda sorun cikmiyor.

time = (3600 *  (10 +(ss2-48))) + (60 * (((dk1-48)*10) + (dk2-48)) ) + (((sn1-48)*10) + (sn2-48));

yada direk saati el ile yazincada sorun olmuyor.

time = (3600 *  14) + (60 * (((dk1-48)*10) + (dk2-48)) ) + (((sn1-48)*10) + (sn2-48));


ilk code larimin char lari normal bir unsigned long a donusturebilmesi gerekmez mi?  :-\ yanlisi nerede yapiyoruz?

mesaj birleştirme:: 02 Eylül 2015, 16:11:41

soyle bir deney yaha yaptim.

              saat = 0;
              if(ss1 == '1') saat = 10;
              if(ss1 == '2') saat = 20;
              
              time = 0;
              time = (3600 * saat) + (60 * ((dk1-48)*10 + dk2-48)) + ((sn1-48)*10 + (sn2-48));


saat unsigned char bir degisken. usb den ss1 okunuyor. suan saat 16 oldugundan '1' seklinde okunuyor. saat degiskenini 10 yapiyor. time in formulasinda saat yerine konunca olmuyor.

formulada saat i silip. 10 yaziyorum. 3600 ile unsigned char saat neden carpilinca sonuc hatali oluyor?

mufitsozen

#1
buyuk ihtimalle overflow!

3600 * 10 * 10 > 32767 (16 bit signed en buyuk + deger)

mesaj birleştirme:: 02 Eylül 2015, 16:28:48

3600 yerine 3600ul dersen bir ihtimal degisir (c soldan saga hesaplar diye hatirliyorum)



mesaj birleştirme:: 02 Eylül 2015, 16:30:09

yada soyle yazarsan
time = (unsigned long)(3600 ....
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

Karamel

#2
simdi anladim. hocamin isigindan yola cikarak suradan http://www.cplusplus.com/articles/DE18T05o/ meseleyi ogrendim. ::)

mesela register 8bit olsun. max 255(11111111) sayisini elde edebiliyoruz.

ama ben buraya mesela 350 yazmaya kalksam. bunun yeni degeri 350 olamiyor. 350-255 yani 95 degerini aliyor. cok mantikliymis ::)


mesaj birleştirme:: 02 Eylül 2015, 18:11:25



hocam yalniz anlamadigim birsey var.

time unsigned long yani 32 bit.

(ss1 ve ss2 den max 24 sayisi gelebilir)
3600*(24) +  60*(0) + 0

time icersine yazmak istedigim en yuksek sayi bu. oda 86399 a denk geliyor. oyleyse time nasil overflow oluyor?  :-\

Gökhan BEKEN

Alıntı yapılan: Karamel - 02 Eylül 2015, 18:09:57
hocam yalniz anlamadigim birsey var.

time unsigned long yani 32 bit.
32 bit olması için "int" olması lazım.
"long" 64 bittir, gerçi "long long" 64 oluyor ama emin değilim.
Özel mesaj okumuyorum, lütfen göndermeyin.

mufitsozen

#4
Alıntı yapılan: Karamel - 02 Eylül 2015, 18:09:57
simdi anladim. hocamin isigindan yola cikarak suradan http://www.cplusplus.com/articles/DE18T05o/ meseleyi ogrendim. ::)

mesela register 8bit olsun. max 255(11111111) sayisini elde edebiliyoruz.

ama ben buraya mesela 350 yazmaya kalksam. bunun yeni degeri 350 olamiyor. 350-255 yani 95 degerini aliyor. cok mantikliymis ::)


mesaj birleştirme:: 02 Eylül 2015, 18:11:25



hocam yalniz anlamadigim birsey var.

time unsigned long yani 32 bit.

(ss1 ve ss2 den max 24 sayisi gelebilir)
3600*(24) +  60*(0) + 0

time icersine yazmak istedigim en yuksek sayi bu. oda 86399 a denk geliyor. oyleyse time nasil overflow oluyor?  :-\

burada hesabi time degiskenine gore değil 3600 sayisina ilk tosladigi icin ona gore yapiyor(dur buyuk ihtimalle- soldan saga islerken). Sabit deyip gecme. Bundan dolayi butun ara degerler short hesaplaniyor olabilir. Eger isini defaulta birakirsan ornegin int 8bitmi(evet bazi piclerde!), 16mi, 32mi, 64mu compiler'a bagli olur. O yuzden sabit sayilari hesaplamalarda overflow'i engelleyecek sekilde tanimlamak, yada buyuklugunu kontrol ettigin bir degisken ile hesaplamaya baslamak degisik cozum metodlari olabilir.

Bende bundan dolayi ya unsigned long cast et yada sabit degerleri default'a birakma 3600ul yaz demistim(boylece hem sabit deger hemde onunla baslayan ara degerler unsigned long olacaktir)

ben c++'dan cok anlamam, o konuda gerbay'a danisirim (ve guvenirim) onuda forumdan kacirdilar. O yuzden ben C icin sana aciklamalar yapacagim. http://publications.gbdirect.co.uk/c_book/chapter2/expressions_and_arithmetic.html bu linkde c'deki bu tip 'gariplikleri' acikliyor. C++'da %95 buna benzerdir diyorum (ama sen yinede beni dinleme, c++ iyi bilen birine sor, yada standard dokumanini okuyup anlamak icin 3-4 seneni ver!  :D )
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.