Capitolul 2.9. Operatori logici pe biti
:: Programare :: C & C++ :: Capitolul 2
Pagina 1 din 1
Capitolul 2.9. Operatori logici pe biti
Limbajul C ofera un numar de operatori pentru manipularea bitilor; acestia nu se pot aplica lui float si double.
& SI bit cu bit
| SAU inclusiv bit cu bit
^ SAU exclusiv bit cu bit
<< deplasare stinga
>> deplasare dreapta
~ complement fata de 1 (unar)
Operatorul SI bit cu bit "&" este folosit adesea pentru a masca anumite multimi de biti; de exemplu
c = n & 0177;
pune pe zero toti biti lui n, mai putin bitul 7 (cel mai tare).
Operatorul SAU bit cu bit "|" este folosit pentru a pune pe 1 biti:
x = x | MASK;
pune pe 1 in x bitii care sint setati pe 1 in MASK.
Trebuie sa distingeti cu grija operatorii pe biti & si | de conectorii logici && si ||, care implica o evaluare de la stinga la dreapta a unei valori de adevar. De exemplu, daca x este 1 si y este 2, atunci x & y este zero dar x && y este 1. (De ce ?)
Operatorii de deplasare << si >> realizeaza deplasari la stinga si la dreapta pentru operandul lor din stinga, cu numarul de pozitii dat de operandul din dreapta lor. Astfel x << 2 deplaseaza la stinga pe x cu doua pozitii, umplind locurile libere cu zero; aceasta este echivalent cu inmultirea cu 4. Deplasind la dreapta o cantitate unsigned, bitii vacanti se umplu cu zero.
Deplasind la dreapta o cantitate cu semn, bitii vacanti se umplu cu semnul ("deplasarea aritmetica") pe anumite calculatoare, ca de exemplu PDP-11 si cu 0 ("deplasare logica") pe altele.
Operatorul unar ~ da complementul fata de 1 al unui intreg; adica, el converteste fiecare bit de 1 in 0 si vicevesa. Acest operator isi gaseste utilitate in expresii de tipul
x & ~077
care mascheaza ultimii 6 biti ai lui x pe 0. De notat ca x & ~077 este independent de lungimea cuvintului si deci preferabil, de exemplu, lui x & 0177700, care presupune ca x este o cantitate cu o lungime de 16 biti. Forma portabila nu implica un cost mai mare, deoarece ~077 este o expresie constanta si deci evaluata la compilare.
Pentru a ilustra folosirea unora din operatorii de biti, sa consideram functia getbits(x,p,n) care returneaza (cadrat la dreapta) cimpul de lungime n biti al lui x care incepe la pozitia p. Presupunem ca bitul 0 este cel mai din dreapta si ca n si p sint valori pozitive sensibile. De exemplu, getbits(x,4,3) returneaza 3 biti in pozitiile 4, 3 si 2, cadrati la dreapta.
getbits (x, p, n) /* ia n biti de la pozitia p */
unsigned x, p, n;
{
return( (x >> (p+1-n) ) & ~(~0 << n));
}
x >> (p+1-n) muta cimpul dorit la sfirsitul din dreapta al cuvintului. Declarind argumentul x ca fiind unsigned ne asiguram ca atunci cind el este deplasat la dreapta bitii vacanti vor fi umpluti cu 0 si nu cu bitii de semn, independent de calculatorul pe care este executat programul. ~0 este cuvintul cu toti bitii pe 1; deplasindu-l la stinga cu n pozitii prin ~0 << n cream o masca cu zerouri pe cei mai din dreapta n biti si 1 in rest; complementindu-l cu ~ facem o masca de 1 pe cei mai din dreapta n biti.
Exercitiul 2.5. Modificati getbits pentru a numara bitii de la stinga la dreapta.
Exercitiul 2.6. Scrieti o functie wordlength() care calculeaza lungimea unui cuvint de pe calculatorul gazda, adica numarul de biti dintr-un int. Functia sa fie portabila in sensul ca acelasi cod sursa sa lucreze pe toate calculatoarele.
Exercitiul 2.7. Scrieti o functie rightrot(n, b) care roteste intregul n la dreapta cu b pozitii.
Exercitiul 2.8. Scrieti o functie invert(x,p,n) care inverseaza (i.e. schimba pe 1 in 0 si viceversa) cei n biti ai lui x care incep de la pozitia p,lasindu-i pe ceilalti neschimbati.
& SI bit cu bit
| SAU inclusiv bit cu bit
^ SAU exclusiv bit cu bit
<< deplasare stinga
>> deplasare dreapta
~ complement fata de 1 (unar)
Operatorul SI bit cu bit "&" este folosit adesea pentru a masca anumite multimi de biti; de exemplu
c = n & 0177;
pune pe zero toti biti lui n, mai putin bitul 7 (cel mai tare).
Operatorul SAU bit cu bit "|" este folosit pentru a pune pe 1 biti:
x = x | MASK;
pune pe 1 in x bitii care sint setati pe 1 in MASK.
Trebuie sa distingeti cu grija operatorii pe biti & si | de conectorii logici && si ||, care implica o evaluare de la stinga la dreapta a unei valori de adevar. De exemplu, daca x este 1 si y este 2, atunci x & y este zero dar x && y este 1. (De ce ?)
Operatorii de deplasare << si >> realizeaza deplasari la stinga si la dreapta pentru operandul lor din stinga, cu numarul de pozitii dat de operandul din dreapta lor. Astfel x << 2 deplaseaza la stinga pe x cu doua pozitii, umplind locurile libere cu zero; aceasta este echivalent cu inmultirea cu 4. Deplasind la dreapta o cantitate unsigned, bitii vacanti se umplu cu zero.
Deplasind la dreapta o cantitate cu semn, bitii vacanti se umplu cu semnul ("deplasarea aritmetica") pe anumite calculatoare, ca de exemplu PDP-11 si cu 0 ("deplasare logica") pe altele.
Operatorul unar ~ da complementul fata de 1 al unui intreg; adica, el converteste fiecare bit de 1 in 0 si vicevesa. Acest operator isi gaseste utilitate in expresii de tipul
x & ~077
care mascheaza ultimii 6 biti ai lui x pe 0. De notat ca x & ~077 este independent de lungimea cuvintului si deci preferabil, de exemplu, lui x & 0177700, care presupune ca x este o cantitate cu o lungime de 16 biti. Forma portabila nu implica un cost mai mare, deoarece ~077 este o expresie constanta si deci evaluata la compilare.
Pentru a ilustra folosirea unora din operatorii de biti, sa consideram functia getbits(x,p,n) care returneaza (cadrat la dreapta) cimpul de lungime n biti al lui x care incepe la pozitia p. Presupunem ca bitul 0 este cel mai din dreapta si ca n si p sint valori pozitive sensibile. De exemplu, getbits(x,4,3) returneaza 3 biti in pozitiile 4, 3 si 2, cadrati la dreapta.
getbits (x, p, n) /* ia n biti de la pozitia p */
unsigned x, p, n;
{
return( (x >> (p+1-n) ) & ~(~0 << n));
}
x >> (p+1-n) muta cimpul dorit la sfirsitul din dreapta al cuvintului. Declarind argumentul x ca fiind unsigned ne asiguram ca atunci cind el este deplasat la dreapta bitii vacanti vor fi umpluti cu 0 si nu cu bitii de semn, independent de calculatorul pe care este executat programul. ~0 este cuvintul cu toti bitii pe 1; deplasindu-l la stinga cu n pozitii prin ~0 << n cream o masca cu zerouri pe cei mai din dreapta n biti si 1 in rest; complementindu-l cu ~ facem o masca de 1 pe cei mai din dreapta n biti.
Exercitiul 2.5. Modificati getbits pentru a numara bitii de la stinga la dreapta.
Exercitiul 2.6. Scrieti o functie wordlength() care calculeaza lungimea unui cuvint de pe calculatorul gazda, adica numarul de biti dintr-un int. Functia sa fie portabila in sensul ca acelasi cod sursa sa lucreze pe toate calculatoarele.
Exercitiul 2.7. Scrieti o functie rightrot(n, b) care roteste intregul n la dreapta cu b pozitii.
Exercitiul 2.8. Scrieti o functie invert(x,p,n) care inverseaza (i.e. schimba pe 1 in 0 si viceversa) cei n biti ai lui x care incep de la pozitia p,lasindu-i pe ceilalti neschimbati.
Subiecte similare
» Capitolul 2.6. Operatori relationali si logici
» Capitolul 2.5. Operatori Aritmetici
» Capitolul 2. TIPURI, OPERATORI SI EXPRESII
» Capitolul 2.8. Operatori de incrementare si decrementare
» Capitolul 2.10.Operatori si expresii de asignare
» Capitolul 2.5. Operatori Aritmetici
» Capitolul 2. TIPURI, OPERATORI SI EXPRESII
» Capitolul 2.8. Operatori de incrementare si decrementare
» Capitolul 2.10.Operatori si expresii de asignare
:: Programare :: C & C++ :: Capitolul 2
Pagina 1 din 1
Permisiunile acestui forum:
Nu puteti raspunde la subiectele acestui forum
|
|