2011-11-28 18 views
5

Necesito extactar bytes del conjunto de bits que pueden (no) contener un múltiplo de bits CHAR_BIT. Ahora, ¿cuántos de los bits del conjunto de bits necesito poner en una matriz? Por ejemplo,¿Cómo convierto bitset a una matriz de bytes/uint8?

los bits puestos está declarada como std::bitset < 40> id;

Hay una variable separada nBits cuántos de los bits en id están disponibles. Ahora quiero extraer esos bits en múltiplos de CHAR_BIT. También necesito ocuparme de los casos donde nBits % CHAR_BIT != 0. Estoy bien para poner esto en una matriz de uint8

+2

Harsh ... si tuviera menos de sizeof (unsigned long) bits, esto sería sencillo con 'bitset :: to_ulong'. Tal como están las cosas, no creo que haya una solución simple. 'std :: bitset' no tiene algo como' data() 'como lo hace' std :: vector' (aunque la versión de gcc tiene una función '_M_getdata' indocumentada y experimental que es solo eso ...)'. Como no hay otra cosa, solo puede acceder a los bits individuales por separado. O serialice en una cadena o vaya a través de una secuencia, pero ninguno de estos es particularmente eficiente. – Damon

Respuesta

3

Lamentablemente, no hay una buena manera en el lenguaje, suponiendo que necesita para que el número de bits en un unsigned long (en cuyo caso podría usar to_ulong). Tendrá que iterar sobre todos los bits y generar la matriz de bytes usted mismo.

15

Puede usar boost::dynamic_bitset, que se puede convertir a un rango de "bloques" usando boost::to_block_range.

#include <cstdlib> 
#include <cstdint> 
#include <iterator> 
#include <vector> 
#include <boost/dynamic_bitset.hpp> 

int main() 
{ 
    typedef uint8_t Block; // Make the block size one byte 
    typedef boost::dynamic_bitset<Block> Bitset; 

    Bitset bitset(40); // 40 bits 

    // Assign random bits 
    for (int i=0; i<40; ++i) 
    { 
     bitset[i] = std::rand() % 2; 
    } 

    // Copy bytes to buffer 
    std::vector<Block> bytes; 
    boost::to_block_range(bitset, std::back_inserter(bytes)); 
} 
+0

Uno de los temas a tener en cuenta es que el tipo interno del vector debe coincidir con el tipo de bloque que se usó para construir el conjunto de bits (en este caso, 'unsigned char'). Si el conjunto de bits tiene bloques de 4 bytes pero el vector tiene bloques de 1 byte, 'to_block' cortará silenciosamente los últimos 3 bytes de cada bloque. Por lo tanto, es algo más seguro cambiar la declaración del vector en la respuesta de Emile a 'std :: vector bytes'. – prideout

+0

Corrección a mi comentario: el tipo interno es 'Bitset :: block_type', no' Bitset :: Block'. – prideout

+0

@prideout: se agregó 'Block' typedef para evitar la situación que describes. –

Cuestiones relacionadas