Jūs esate neprisijungęs lankytojas. Norint dalyvauti diskusijose, būtina užsiregistruoti ir prisijungti prie forumo.
Prisijungę galėsite kurti naujas temas, atsakyti į kitų užduotus klausimus, balsuoti forumo apklausose.
Administracija pasilieka teisę pašalinti pasisakymus bei dalyvius,
kurie nesilaiko forumo taisyklių.
Pastebėjus nusižengimus, prašome pranešti.
Dabar yra 2025 04 16, 00:27. Visos datos yra GMT + 2 valandos.
Jūs negalite rašyti naujų pranešimų į šį forumą Jūs negalite atsakinėti į pranešimus šiame forume Jūs negalite redaguoti savo pranešimų šiame forume Jūs negalite ištrinti savo pranešimų šiame forume Jūs negalite dalyvauti apklausose šiame forume
tuomet šis skaičius kaip suprantu gali būti 0-65535. O kaip tada matematinių veiksmų sąlygomis jeigu kažkurioje skaičiavimo dalyje jis perkopia šias reikšmes, pvz:
Kodas:
define F_CPU 16000000
unsigned int x;
x=1000;
skaicius= F_CPU/(100*x)
apskaičiavus "skaičių" gaunasi 160, t.y. 16000000/100*1000. Taigi 160 kaip ir telpa į "skaičiaus" unsigned int rėmus, nes mažesnis už 65535.
Bet kaip yra pačio skaičiavimo metu AVR? Kaip vyksta skaičiavimas? "skaičius" iš pradžių pasiima 16000000, paskui dalina iš 100, o paskui iš 1000. Ar iš pradžių susidaugina 100*1000, kuomet gauna 100000, kas yra daugiau už unsigned int. Ta prasme skaičiuojant, tam tikrais etapais turim didesnius skaičius negu unsigned int rėmai, nors atsakymas kaip telpa. Ar negali būti taip, kad tuo momentu kuomet skaičius peržengs 65535, jis tiesiog taps 65535 ir skaičiuos toliau?
Kaip čia iš tikro yra?
Ačiū.
_________________ Aš pažeidžiau forumo taisykles ir reklamavau paraše. ...Bet uz reklama tai susimokejau
Tai kompiliatoriaus reikalas, kaip jis paskaiciuoja konstantas
tokiais atvejais gale skaitmenines konstantos prirasyk L arba UL
#define F_CPU 16000000L
#define F_CPU 16000000UL
#define F_CPU 16000000l
#define F_CPU 16000000ul
unsigned int x;
x=1000; // cia viskas gerai, kadangi 1000 puikiai telpa i unsigned int
Tai tie UL arba L tiesiog nusako, kad konkrečiam skaičiavimo veiksme skaičiai yra (unsigned)long?
Kodas:
#define F_CPU 16000000UL
unsigned int skaicius;
skaicius= F_CPU/(100ul*x)
o paskui jau gautas po veiksmo unsigned long perkeliamas į skaičių, kuris šiuo atveju yra unsigned int? Na jeigu gautas rezultatas butu didesnis uz 65535, tai tas pėkėlimas nesigautų teisingas?
_________________ Aš pažeidžiau forumo taisykles ir reklamavau paraše. ...Bet uz reklama tai susimokejau
Tam ir reikia pazymeti ul, kad neatsirastu zenklas, kai vienas is operandu pasidaro > 32767, t.y. int variante gaunasi -32768 => -1, nes kompiliatorius pagal nutylejima operuoja int tipais.
tas pats gautusi jei vienoje formuleje sumaisytum char, unsigned char
jei skaicius gautusi > 127, tai jis igautu zenkla, pvz:
char n = 128; // cia ivyksta virsmas i -128 arba 0x80
if ( n == 128 ) // butu klaida, nes 128 != -128
if ( n == 0x80 ) // ok, nes 0x80 == -128
kad neivyktu nesusipratimu, reikia naudoti unsigned char
Tam ir reikia pazymeti ul, kad neatsirastu zenklas, kai vienas is operandu pasidaro > 32767, t.y. int variante gaunasi -32768 => -1, nes kompiliatorius pagal nutylejima operuoja int tipais.
tas pats gautusi jei vienoje formuleje sumaisytum char, unsigned char
jei skaicius gautusi > 127, tai jis igautu zenkla, pvz:
char n = 128; // cia ivyksta virsmas i -128 arba 0x80
if ( n == 128 ) // butu klaida, nes 128 != -128
if ( n == 0x80 ) // ok, nes 0x80 == -128
kad neivyktu nesusipratimu, reikia naudoti unsigned char
Ačiū Algi. Tai reiškias yra rekomenduojama visur naudoti tuos UL kur pliki skaičiai. Arba UI, jeigu unsigned int?
_________________ Aš pažeidžiau forumo taisykles ir reklamavau paraše. ...Bet uz reklama tai susimokejau
Algi, bet čia tiesiogiai apibūdinai kaip lygini signed ir unsigned char. Bet kaip būtų jei tarpiniai skaičiavimai viršina ribą, nors galutinis atsakymas jau neturėtų viršyti. Man atrodo autorius ne visai to klausė. pvz jei kintamasis unsigned char, bet skaičiuoji (2000*2)/100. rezultatas 40, telpa į rėmus, bet pirmas veiksmas 2000*2 jau išlenfa iš char rėmų.
įdomumo dėlei pabandiau su gcc ir nxp procu, tai rezultate gavau 40, kaip ir teisingai, vadinasi veiksmus vykdo nepriklausomai nuo kintamojo, kuriam priskiriama galutinė reikšmė.
Algi, bet čia tiesiogiai apibūdinai kaip lygini signed ir unsigned char. Bet kaip būtų jei tarpiniai skaičiavimai viršina ribą, nors galutinis atsakymas jau neturėtų viršyti. Man atrodo autorius ne visai to klausė. pvz jei kintamasis unsigned char, bet skaičiuoji (2000*2)/100. rezultatas 40, telpa į rėmus, bet pirmas veiksmas 2000*2 jau išlenfa iš char rėmų.
įdomumo dėlei pabandiau su gcc ir nxp procu, tai rezultate gavau 40, kaip ir teisingai, vadinasi veiksmus vykdo nepriklausomai nuo kintamojo, kuriam priskiriama galutinė reikšmė.
iskas ok, kol naudoji konstantas, kurios telpa i int, jokiu prierasu nereikia
char t1 = (2000*2)/100; // ok, gausi 40
char t2 = (20000*2)/1000; // jau gausi -40
char t3 = (20000ul*2)/1000; // vel gausi 40
char t4 = (20000L*2)/1000; // irgi gausi 40
char t5 = (20000L*2)/100; // ne ok, nes vietoje 400 gausi -112
Kaip suprantu nėra svarbu kuriam skaičiui prirašyt UL, t.y. (100*1000UL)/100 ar (100UL*1000)/100?
Ir esant sudėtingesnei formulei būna pasigavę tą pirmąjį UL nustatymą, todėl jeigu sekančiuose skaičiavimuose išlipa iš INT ribų, vistiek gerai skaičiuoja, pvz:
skaicius=(((100*1000UL)/100)*100)/5
_________________ Aš pažeidžiau forumo taisykles ir reklamavau paraše. ...Bet uz reklama tai susimokejau
Tikrai tai, nes kaip minejau, kompiliatorius pagal nutylejima naudoja INT tikslumo aritmetika konstantos paskaiciavimui, kol nenurodai jam jog tau reikia LONG.
Beje, pasirenkant kintamuju tipa, reikia pasirupinti, kad skaiciavimo rezultatas tilptu i kintamojo tipo remus.
Tas pats būna ir junginėjant įvairius registrus, tarkim nustatančius taimerio darbą. Nors kartais veikia tvarkingai. Buvau nurašęs kaip kompiliatoriaus bugą (Avr studio5), bet su 7 versija vėl taspats..
_________________ Aš pažeidžiau forumo taisykles ir reklamavau paraše. ...Bet uz reklama tai susimokejau