Documente Academic
Documente Profesional
Documente Cultură
~ complementare
<< deplasare la stânga (left shift), >> deplasare la dreapta (right shift)
& și (conjuncție)
^ sau exclusiv
| sau (disjuncție)
Operatorul ~ transforma fiecare bit din reprezentarea operandului în
complementarul său, adică biții 1 în 0 și biții 0 în 1:
b ~b
0 1
1 0
Exemplu:
0…0 1111 1111 1010 0001 &
0…0 1110 0010 0001 0011
--------------------------------
0…0 1110 0010 0000 0001
e 2 0 1
return 0;
}
Programul afișează
0xffa1 & 0xe213 = 0xe201
0xffa1 ^ 0xe213 = 0x1db2
0xffa1 | 0xe213 = 0xffb3
~ 0xffa1 = 0xffff005e
~ 0xe213 = 0xffff1dec
Operatorul de deplasare la stânga (left shift) << este un operator binar care are ca
rezultat numărul obținut prin deplasare spre stânga a biților din reprezentarea în memorie
a primului operand cu un număr de poziții egal cu al doilea operand.
Operatorul de deplasare la dreapta (right shift) >> este un operator binar care are ca
rezultat numărul obținut prin deplasare spre dreapta a biților din reprezentarea în memorie
a primului operand cu un număr de poziții egal cu al doilea operand.
Deci operatorii de deplasare sunt binari, primul operand este cel ai cărui biți sunt
deplasați, iar al doilea indică numărul de biți cu care se face deplasarea.
a << n
a >> n
La deplasarea la stânga cu o poziție, bitul cel mai semnificativ se pierde, iar in dreapta se
completează cu bitul 0. La deplasarea la dreapta cu o poziție, bitul cel mai puțin
semnificativ se pierde, iar în stânga se completează cu 0 (pentru operanzi fără semn sau cu
semn nenegativi). În cazul în care operandul din stânga este negativ, completarea bitului
din stânga (cel mai semnificativ) depinde de implementare (de obicei se adaugă un bit
identic cu cel de semn).
Pentru operanzi fără semn sau cu semn nenegativi, cu excepția cazurilor când se
produce depășire, deplasarea la stânga cu n biți echivalează cu înmulțirea cu 2n.
Deplasarea la dreapta cu n biți echivalează cu împărțirea la 2n.
Începând cu standardul C++20, valoarea expresiei a << n este egală cu a*2n modulo
2N, unde N este numărul de biți asociat tipului rezultatului. Valoarea expresiei a >> n este
partea întreagă a a/2n.
Dacă valoarea operandului drept este negativă sau este mai mare sau egală cu
numărul de biți din operandul stâng (promovat), comportamentul operatorilor de deplasare
este nedefinit.
Probleme rezolvate
#include <iostream>
#include <cstdint>
int main () {
uint8_t masca = 0xf1; //masca = 0b11110001
uint16_t x;
std::cout << std::hex << std::showbase;
std::cout << (unsigned) masca << std::endl;
std::cin.unsetf (std::ios::dec);
std::cin.unsetf (std::ios::hex);
std::cin.unsetf (std::ios::oct);
std::cout << "x = ";
std::cin >> x;
std::cout << "marcarea cu 1 a bitilor: " << (x | masca) << '\n'
<< "marcarea cu 0 a bitilor: " << (x & ~masca) << '\n'
<< "Selectarea bitilor: " << (x & masca) << std::endl;
return 0;
}
#include <iostream>
#include <climits>
int main() {
long long int x;
unsigned long long int ux, masca = 0;
std::cin.unsetf(std::ios::dec);
std::cin.unsetf(std::ios::hex);
std::cin.unsetf(std::ios::oct);
std::cout << "x = ";
std::cin >> x;
if(x == 0){
std::cout << '0';
}
else {
if (x < 0) {
ux = (unsigned long long int) (- x);
std::cout << '-';
}
else {
ux= (unsigned long long int) x;
}
masca = 1ull << (sizeof(ux)*CHAR_BIT - 1 );
while ((ux & masca) == 0) {
masca >>= 1;
}
while (masca) {
if (ux & masca) {
std::cout << '1';
}
else {
std::cout << '0';
}
masca >>= 1;
}
}
std::cout << std::endl;
return 0;
}
#include <iostream>
int main() {
unsigned long long int x;
unsigned int p, q, vaux;
std::cout << "p = "; std::cin >> p;
std::cout << "q = "; std::cin >> q;
if (p > q) {
vaux = p;
p = q;
q = vaux;
}
x = ((1ull << p) - 1) ^ ((1ull << q+1) - 1);
std::cout << std::hex << std::showbase << x << std:: endl;
return 0;
}
Variantă cu reprezentare binară
#include <iostream>
#include <climits>
int main() {
unsigned long long int x, masca = 0;
unsigned int p, q, vaux;
std::cout << "p = "; std::cin >> p;
std::cout << "q = "; std::cin >> q;
if (p > q) {
vaux = p;
p = q;
q = vaux;
}
x = ((1ull << p) - 1) ^ ((1ull << q+1) - 1);
std::cout << std::hex << std::showbase << x << std:: endl;
if(x == 0){
std::cout << '0';
}
else {
masca = 1ull << (sizeof(x)*CHAR_BIT - 1 );
while ((x & masca) == 0) {
masca >>= 1;
}
while (masca) {
if (x & masca) {
std::cout << '1';
}
else {
std::cout << '0';
}
masca >>= 1;
}
}
std::cout << std::endl;
return 0;
}
#include <iostream>
int main() {
int x[] = {1, 2, 1, 3, 4, 4, 2, 5}, n = 8, i, xor_x, xor_x1, xor_x2, bit_test;
xor_x = x[0];
for(i = 1; i < n; ++i) {
xor_x ^= x[i];
}
bit_test = xor_x & ~(xor_x - 1);
xor_x1 = 0;
xor_x2 = 0;
for(i = 0; i < n; ++i){
if(x[i] & bit_test) {
xor_x1 ^= x[i];
}
else {
xor_x2 ^= x[i];
}
}
std::cout<<xor_x1<<' '<<xor_x2<<std::endl;
return 0;
}
Probleme propuse
1. Se dau două numere întregi fără semn n și k. Să se determine câtul (întreg) și restul
împărțirii lui n la 2k.
2. Se dă un număr întreg fără semn n. Să se verifice dacă n este o putere a lui 2.
3. Să se determine cel mai mare număr întreg k cu proprietatea că 2k divide un număr
întreg fără semn n dat.
4. Se dă un tablou cu elemente întregi în care fiecare valoare apare de un număr par
de ori cu excepția uneia. Să se determine valoarea respectivă
5. (Temă minimală). Se dă un număr întreg fără semn n. Să se determine numărul
întreg fără semn a cărui reprezentare binară coincide cu secvența de cifre din
reprezentarea binară a numărului n de la bitul p (corespunzător puterii 2p) până la
bitul q (corespunzător puterii 2q), cu p și q date.