2015-04-27 15 views
8

È facile costruire un bitset<64> da un uint64_t:Costrutto bitset da array di interi

uint64_t flags = ...; 
std::bitset<64> bs{flags}; 

Ma c'è un buon modo per costruire un bitset<64 * N> da un uint64_t[N], tale che flags[0] rinvio alla basse 64 bit ?

uint64_t flags[3]; 
// ... some assignments 
std::bitset<192> bs{flags}; // this very unhelpfully compiles 
          // yet is totally invalid 

o sono io bloccato dover chiamare set() in un ciclo?

+4

Vuoi dire di prendere il più basso 8 bit da ogni 'uint64_t'? E in quale ordine? – Wintermute

+0

@Wintermute Oops. Voglio tutti i bit. 'flags [0]' sarebbe il più basso 64 bit. – Barry

+0

Forse qualcosa come 'constexpr std :: size_t FLAGS_SIZE = 3; uint64_t flags [FLAGS_SIZE]; std :: bitset <64 * FLAGS_SIZE>(); '? – chessbot

risposta

9

std::bitset non ha alcun costruttore di intervallo, quindi è necessario eseguire il ciclo, ma l'impostazione di ogni singolo bit con std::bitset::set() è insufficiente. std::bitset ha il supporto per gli operatori binari, in modo da poter impostare almeno 64 bit alla rinfusa:

std::bitset<192> bs; 

    for(int i = 2; i >= 0; --i) { 
    bs <<= 64; 
    bs |= flags[i]; 
    } 

Update: Nei commenti, @icando solleva la preoccupazione legittima che bitshifts sono operazioni O (n) per std::bitset s . Per bitset molto grandi, questo alla fine mangerà l'aumento prestazionale dell'elaborazione di massa. Nel mio riferimento, il punto di pareggio per un std::bitset<N * 64> rispetto ad un semplice ciclo che imposta i bit singolarmente e non mutare dati di input:

int pos = 0; 
for(auto f : flags) { 
    for(int b = 0; b < 64; ++b) { 
    bs.set(pos++, f >> b & 1); 
    } 
} 

si aggira intorno N == 200 (gcc 4.9 su x86-64 con libstdC++ e -O2). Clang si comporta un po 'peggio, superando anche lo N == 160. Gcc con -O3 lo spinge fino a N == 250.

Prendere l'estremità inferiore, questo significa che se si desidera lavorare con bitset di 10000 bit o più grandi, questo approccio potrebbe non essere adatto a voi. Su piattaforme a 32 bit (come le ARM comuni), la soglia sarà probabilmente inferiore, quindi tienilo a mente quando lavori con bitset a 5000 bit su tali piattaforme. Tuttavia, direi che da qualche parte molto prima di questo punto, dovresti chiederti se un bitset è davvero la scelta giusta per il contenitore.

+0

Se bs è il set di bit , allora lo spostamento è un'operazione 'O (N)', quindi il ciclo generale è un'operazione 'O (N^2)'. Nessuno l'ha notato? –

+0

@icando Siete più che benvenuti a postare una risposta migliore. – Barry

+1

@Barry, quello che hai detto, "O sono bloccato a dover chiamare set() in un ciclo?", È in realtà una soluzione migliore di questo. Hai accettato una soluzione O (N^2) dato che hai tu stesso una soluzione O (N), il che è strano. –

-1

Se l'inizializzazione della gamma è importante, si potrebbe considerare l'utilizzo di std :: vector

Essa ha ancora costruttore dalla coppia di iteratori