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 modificatoruluiconst
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ă valoarea1
pentruB[k]
B.set(k , r)
dă valoarear
pentruB[k]
B.set()
dă valoarea1
pentru toți biții dinB
- resetarea unui bit precizat:
B.reset(k)
dă valoarea0
pentruB[k]
B.reset()
dă valoarea0
pentru toți biții dinB
- schimbarea valoare biților (din
1
devine0
, iar din0
devine1
):B.flip(k)
schimbă valoarea luiB[k]
B.flip()
schimbă valorile pentru toți biții dinB
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 cuA = A & B
;A |= B
este echivalent cuA = A | B
;A ^= B
este echivalent cuA = A ^ B
;A <<= n
este echivalent cuA = A << n
;A >>= n
este echivalent cuA = A >> n
;
Conversii
Bitset-ul poate fi convertit la
- string –
to_string
B.to_string()
– returnează un string conținând reprezentarea binară a luiB
, formată formată din caractere0
și1
;B.to_string(c0)
– returnează un string conținând reprezentarea binară a luiB
, caracterele0
fiind înlocuite cu caracterulc0
;B.to_string(c0 , c1)
– returnează un string conținând reprezentarea binară a luiB
, caracterele0
și1
fiind înlocuite cu caracterulc0
, respectivc1
;
- î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 bitsetuluiB
;B.to_uulong()
– retunează un întreg fără semn pe 64 de biți (unsigned long long
) cu reprezentarea binară echivalentă cu configurația bitsetuluiB
;- 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
.