|
|
Elektronika.lt portalo forumas
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 2024 11 22, 00:47. Visos datos yra GMT + 2 valandos.
|
|
|
|
Forumas » Mikrovaldikliai » AVR matematika
|
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
|
|
|
Puslapis 1 iš 2 Pereiti prie 1, 2 Toliau |
|
|
|
|
AVR matematika |
Parašytas: 2018 11 04, 18:45 |
|
|
|
Sveiki,
norėjau paklaust. Tarkim turim parašę:
Kodas: |
unsigned int skaicius |
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 |
|
|
|
|
|
AVR matematika |
Parašytas: 2018 11 04, 21:07 |
|
|
|
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
skaicius= F_CPU/(100L*x)
skaicius= F_CPU/(100ul*x)
jei operacijoje dalyvauja bezenkliai operandai, prirasyk UL, ul
jei su zenklu - L, l |
|
|
|
|
|
|
AVR matematika |
Parašytas: 2018 11 04, 22:58 |
|
|
|
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 |
|
|
|
|
|
AVR matematika |
Parašytas: 2018 11 05, 09:37 |
|
|
|
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 |
|
|
|
|
|
|
AVR matematika |
Parašytas: 2018 11 05, 12:37 |
|
|
|
AlgisL rašo: |
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 |
|
|
|
|
AVR matematika |
Parašytas: 2018 11 05, 13:19 |
|
|
|
Taip, ir cia ne AVR kaltas, o toks 8bit (ir ne tik) GCC (ir ne tik) sutartas elgesys. |
|
|
|
|
|
AVR matematika |
Parašytas: 2018 11 05, 14:05 |
|
|
|
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ė. |
|
|
|
|
|
|
AVR matematika |
Parašytas: 2018 11 05, 15:58 |
|
|
|
minex rašo: |
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 |
|
|
|
|
|
|
AVR matematika |
Parašytas: 2018 11 05, 16:02 |
|
|
|
Algis vistiek užvedė ant kelio, štai radau labiau man patinkančius atsakymus:
https://www.avrfreaks.net/forum/ul-define-fcpu-1200000ul
vakare pabandysiu kaip iš tikro gaunasi, kuris variantas gauna teisingą atsakymą:
Kodas: |
unsigned long x = 150*1000 |
ar
Kodas: |
unsigned long x = 150UL*1000 |
bet gal būt gali būti ir:
Kodas: |
unsigned long x = 150UL*1000UL |
|
|
_________________ Aš pažeidžiau forumo taisykles ir reklamavau paraše. ...Bet uz reklama tai susimokejau |
|
|
|
|
AVR matematika |
Parašytas: 2018 11 05, 16:57 |
|
|
|
Kai pirma pagal kalkuliacijos logika konstanta nurodai UL, toliau jis ir dirba su UL, kitaip - su INT16 |
|
|
|
|
|
AVR matematika |
Parašytas: 2018 11 06, 21:34 |
|
|
|
Pabandžiau su atmega:
skaicius=(100*1000)/100 gaunasi nesamonė
skaicius=(100*1000UL)/100 gaunasi teisingai.
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 |
|
|
|
|
AVR matematika |
Parašytas: 2018 11 07, 10:04 |
|
|
|
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. |
|
|
|
|
|
AVR matematika |
Parašytas: 2019 01 15, 20:15 |
|
|
|
Labą vakarą dar kartą,
gal specai galėtų patart, kame bėdos.
Noriu įjungt ir išjungt kelis atmegos porto bitus tuo pačiu metu, darau pvz:
Kodas: |
PORTE|=(1<<0)|(1<<1);
delay;
PORTE&=~(1<<0)|(1<<1); |
ir gaunasi blogai, abiejų neišjungia (tiksliau 1 bito), jei padarau atskirai:
Kodas: |
PORTE&=~(1<<0);
PORTE&=~(1<<1); |
veikia.
Kodėl neveikia šita dalis:
Kodas: |
PORTE&=~(1<<0)|(1<<1); |
niekaip nesuprantu, nors analogiška įjungianti du bitus veikia.
ačiū |
|
_________________ Aš pažeidžiau forumo taisykles ir reklamavau paraše. ...Bet uz reklama tai susimokejau |
|
|
|
|
AVR matematika |
Parašytas: 2019 01 15, 20:19 |
|
|
|
P.S.
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 |
|
|
|
|
AVR matematika |
Parašytas: 2019 01 16, 03:36 |
|
|
|
PORTE&=~( (1<<0)|(1<<1) ); |
|
|
|
|
|
|
Google paieška forume |
|
|
Naujos temos forume |
|
|
FS25 Tractors
Farming Simulator 25 Mods,
FS25 Maps,
FS25 Trucks |
|
ETS2 Mods
ETS2 Trucks,
ETS2 Bus,
Euro Truck Simulator 2 Mods
|
|
FS22 Tractors
Farming Simulator 22 Mods,
FS22 Maps,
FS25 Mods |
|
VAT calculator
VAT number check,
What is VAT,
How much is VAT |
|
LEGO
Mänguköök,
mudelautod,
nukuvanker |
|
Thermal monocular
Thermal vision camera,
Night vision ar scope,
Night vision spotting scope |
|
FS25 Mods
FS25 Harvesters,
FS25 Tractors Mods,
FS25 Maps Mods |
|
Dantų protezavimas
All on 4 implantai,
Endodontija mikroskopu,
Dantų implantacija |
|
FS25 Mods
FS25 Maps,
FS25 Cheats,
FS25 Install Mods |
|
GTA 6 Weapons
GTA 6 Characters,
GTA 6 Map,
GTA 6 Vehicles |
|
FS25 Mods
Farming Simulator 25 Mods,
FS25 Maps |
|
|
|