Operatori logici pe biti
Limbajul C ofera un numar de operatori pentru manipularea biti-
lor; 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 deplasea-
za 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 prefe-
rabil, 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;
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; complemen-
tindu-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 calculea-
za 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.