bitset este un container special din STL care permite lucrul cu șiruri de biți. Aceștia sunt memorați eficient, pentru un bit din șir folosindu-se un bit în memorie. Astfel, spațiul de memorie ocupat de un bitset cu M
biți este mai mic decât un tablou bool V[M];
sau un vector cu elemente de tip bool, dar numărul de biți M
din bitset trebuie să fie cunoscut în momentul compilării, deci trebuie să fie o contantă.
Pot fi folosiți de exemplu pe post de vectori caracteristici, dar suportă și operațiile pe biți cunoscute pentru tipurile întregi.
Declararea
Pentru a folosi containerul bitset trebuie inclus headerul bitset
:
#include <bitset>
Declararea se face astfel:
const int M = 16;
bitset<M> B = 30;
Operații elementare
Afișarea
const int M = 16;
bitset<M> B = 30;
cout << B << endl;
Observații:
M
este constantă. Lipsa modificatorului const
duce la o eroare de compilare.
- Când afișăm bitsetul, se afișează toți cei
M
biți.
Indexarea
Biții din bitset sunt indexați de la 0
și pot fi accesați prin operatorul []
. Bitul cel mai nesemnificativ (cel mai din dreapta) este B[0]
, iar bitul cel mai semnificativ este B[M-1]
, unde M
este dimensiunea bitsetului.
const int M = 16;
bitset<M> B = 30; // 0000000000011110
B[6] = 1;
cout << B; // 0000000001011110
Compararea
Două containere bitset de aceeași dimensiune pot fi comparate cu operatorii ==
și !=
.
Notă: operația !=
este eliminată în C++20.
Atribuirea
Putem să-i atribuim unui bitset valoarea unui întreg sau valoarea unui alt bitset. Prin atribuirea unui întreg, biții din bitsetul B
devin identici cu biții din reprezentarea în memorie a valorii întregi care se atribuie:
const int M = 16;
bitset<M> B, A;
B = -30;
cout << B << endl; // 1111111111100010
B = 5;
cout << B << endl; // 0000000000000101
A = B;
cout << A << endl; // 0000000000000101
Manipularea biților
Numărarea bitilor setați, numărul total de biți
Pentru a afle câți biți din bitset sunt setați (au valoarea 1
), folosim metoda count()
. Pentru a determina numărul total de biți, folosim metoda size()
. Numărul biților nesetați (cu valoarea 0
), facem diferența celor două.
const int M = 16;
bitset<M> B = 63;
cout << B.count() << endl; // 6
cout << B.size() << endl; // 16
Determinarea valorii unui bit
Se face cu metoda test(k)
, unde k
reprezintă numărul de ordine al bitului dorit (de la dreapta spre stânga, incepând de la 0
), iar rezultatul este 1
sau 0
.
const int M = 16;
bitset<M> B = 63;
cout << B << endl; // 0000000000111111
cout << B.test(5) << endl; // 1
cout << B.test(6) << endl; // 0
Set, reset, flip
Bitsetul oferă metode pentru:
- setarea unui bit precizat:
B.set(k)
dă valoarea 1
pentru B[k]
B.set(k , r)
dă valoarea r
pentru B[k]
B.set()
dă valoarea 1
pentru toți biții din B
- resetarea unui bit precizat:
B.reset(k)
dă valoarea 0
pentru B[k]
B.reset()
dă valoarea 0
pentru toți biții din B
- schimbarea valoare biților (din
1
devine 0
, iar din 0
devine 1
):
B.flip(k)
schimbă valoarea lui B[k]
B.flip()
schimbă valorile pentru toți biții din B
bitset<M> B;
B = 63;
cout << B << endl; // 0000000000111111
//bitii se numeroteaza de la dreapta, incepand cu 0
B.reset(5);
B.set(10);
B.set(9 , 1);
B.set(3 , 0);
B.flip(2);
cout << B << endl; // 0000011000010011
B.flip();
cout << B << endl; // 1111100111101100
B.set();
cout << B << endl; // 1111111111111111
B.reset();
cout << B << endl; // 0000000000000000
Operații pe biți
Operatii logice pe biți
Clasa bitset suportă operatorii logici pe biți (~
, &
, |
, ^
).
bitset<M> B, A;
B = -60; A = 5;
cout << "A = " << A << endl; // 0000000000000101
cout << "B = " << B << endl; // 1111111111000100
cout << "~B = " << ~B << endl; // 0000000000111011
cout << "A & B = " << (A & B) << endl; // 0000000000000100
cout << "A | B = " << (A | B) << endl; // 1111111111000101
cout << "A ^ B = " << (A ^ B) << endl; // 1111111111000001
Operatorii de deplasare
Clasa bitset suportă operatorii de deplasare a biților (<<
, >>
).
bitset<M> B;
int n = 4;
B = 7;
cout << "B = " << B << endl; // 0000000000000111
cout << "B << n = " << (B << n) << endl; // 0000000001110000
Atribuiri
Clasa bitset suportă atriburile scurte: &=
, |=
, ^=
, precum și <<=
, >>=
.
Fie A
, B
două containere bitset de aceași dimensiune și n
un întreg. Atunci:
A &= B
este echivalent cu A = A & B
;
A |= B
este echivalent cu A = A | B
;
A ^= B
este echivalent cu A = A ^ B
;
A <<= n
este echivalent cu A = A << n
;
A >>= n
este echivalent cu A = A >> n
;
Conversii
Bitset-ul poate fi convertit la
- string –
to_string
B.to_string()
– returnează un string conținând reprezentarea binară a lui B
, formată formată din caractere 0
și 1
;
B.to_string(c0)
– returnează un string conținând reprezentarea binară a lui B
, caracterele 0
fiind înlocuite cu caracterul c0
;
B.to_string(c0 , c1)
– returnează un string conținând reprezentarea binară a lui B
, caracterele 0
și 1
fiind înlocuite cu caracterul c0
, respectiv c1
;
- întreg fără semn-
to_ulong()
, to_uulong()
B.to_ulong()
– retunează un întreg fără semn pe 32 de biți (unsingned int
, unsigned long
) cu reprezentarea binară echivalentă cu configurația bitsetului B
;
B.to_uulong()
– retunează un întreg fără semn pe 64 de biți (unsigned long long
) cu reprezentarea binară echivalentă cu configurația bitsetului B
;
- dacă valoarea întreagă corespunzătoare bitsetului nu poate fi reprezentată pe 32, respectiv 64 de biți, se va ridica o excepție de tip
overflow_error
.
Standard Template Library – STL