2010-04-21 40 views
13

¿Cómo puedo convertir un entero en su representación de bits? Quiero tomar un número entero y devolver un vector que contiene 1 y 0 de la representación de bits del número entero.Convertir entero a una representación de bits

Estoy teniendo un montón de tiempo tratando de hacer esto por mí mismo, así que pensé en preguntar si había una función de biblioteca incorporada que pudiera ayudar.

+2

Creo que te refieres a _bit_ representation. – fbrereto

+5

¿Es esta tarea? – fbrereto

+0

Dado que un número entero es de tamaño fijo, ¿por qué no simplemente usar una matriz simple? –

Respuesta

13

No funciona con negativos.

vector<int> convert(int x) { 
    vector<int> ret; 
    while(x) { 
    if (x&1) 
     ret.push_back(1); 
    else 
     ret.push_back(0); 
    x>>=1; 
    } 
    reverse(ret.begin(),ret.end()); 
    return ret; 
} 
+0

¡Muchas gracias! :) Ahora puedo implementar el algoritmo de la manera que originalmente pretendí. : D – bobber205

+3

O 'hacer ret.push_back (x & 1) while (x >> = 1);' - esta versión devuelve un bit cero para la entrada cero. – Potatoswatter

0

peor número entero del mundo a tan bytes convertidor:

#include <algorithm> 
#include <functional> 
#include <iterator> 
#include <stdlib.h> 

class zero_ascii_iterator: public std::iterator<std::input_iterator_tag, char> 
{ 
public: 
    zero_ascii_iterator &operator++() 
    { 
     return *this; 
    } 

    char operator *() const 
    { 
     return '0'; 
    } 
}; 


char bits[33]; 

_itoa(value, bits, 2); 
std::transform(
    bits, 
    bits + strlen(bits), 
    zero_ascii_iterator(), 
    bits, 
    std::minus<char>()); 
+3

Wow. Me pregunto por qué Perl obtuvo la reputación de ser incomprensible =) – maerics

+0

Definitivamente merece un espacio exclusivo @ codinghorror. – jweyrich

+0

Este es un ejemplo de la vida real? – Potatoswatter

2

Aquí está una versión que funciona con números negativos:

string get_bits(unsigned int x) 
{ 
    string ret; 
    for (unsigned int mask=0x80000000; mask; mask>>=1) { 
    ret += (x & mask) ? "1" : "0"; 
    } 
    return ret; 
} 

La cadena puede, por supuesto, ser reemplazado por un vector o indexado para valores de bit.

3

Una modificación de la respuesta de DCP. El comportamiento es la implementación definida para los valores negativos de t. Proporciona todos los bits, incluso los ceros a la izquierda. Advertencias estándar relacionadas con el uso de std::vector<bool> y no es un contenedor adecuado.

#include <vector> //for std::vector 
#include <algorithm> //for std::reverse 
#include <climits> //for CHAR_BIT 

template<typename T> 
std::vector<bool> convert(T t) { 
    std::vector<bool> ret; 
    for(unsigned int i = 0; i < sizeof(T) * CHAR_BIT; ++i, t >>= 1) 
    ret.push_back(t & 1); 
    std::reverse(ret.begin(), ret.end()); 
    return ret; 
} 

Y una versión que [podría] funcionar también con valores de coma flotante. Y posiblemente otros tipos de POD. Realmente no he probado esto en absoluto. Podría funcionar mejor para valores negativos, o podría funcionar peor. No lo he pensado mucho.

template<typename T> 
std::vector<bool> convert(T t) { 
    union { 
    T obj; 
    unsigned char bytes[sizeof(T)]; 
    } uT; 
    uT.obj = t; 

    std::vector<bool> ret; 
    for(int i = sizeof(T)-1; i >= 0; --i) 
    for(unsigned int j = 0; j < CHAR_BIT; ++j, uT.bytes[i] >>= 1) 
     ret.push_back(uT.bytes[i] & 1); 
    std::reverse(ret.begin(), ret.end()); 
    return ret; 
} 
+0

Endianess probablemente aparezca en el segundo, ¿eh? Oh bien. –

1

Devuelve una cadena en lugar de un vector, pero se puede cambiar fácilmente.

template<typename T> 
std::string get_bits(T value) { 
    int size = sizeof(value) * CHAR_BIT; 
    std::string ret; 
    ret.reserve(size); 
    for (int i = size-1; i >= 0; --i) 
     ret += (value & (1 << i)) == 0 ? '0' : '1'; 
    return ret; 
} 
6

No es demasiado difícil de resolver con un trazador de líneas, pero en realidad hay una solución de biblioteca estándar.

#include <bitset> 
#include <algorithm> 

std::vector<int> get_bits(unsigned long x) { 
    std::string chars(std::bitset< sizeof(long) * CHAR_BIT >(x) 
     .to_string< char, std::char_traits<char>, std::allocator<char> >()); 
    std::transform(chars.begin(), chars.end(), 
     std::bind2nd(std::minus<char>(), '0')); 
    return std::vector<int>(chars.begin(), chars.end()); 
} 

C++ 0x incluso lo hace más fácil!

#include <bitset> 

std::vector<int> get_bits(unsigned long x) { 
    std::string chars(std::bitset< sizeof(long) * CHAR_BIT >(x) 
     .to_string(char(0), char(1))); 
    return std::vector<int>(chars.begin(), chars.end()); 
} 

Este es uno de los rincones más extraños de la biblioteca. Tal vez en realidad lo que estaban manejando era la serialización.

cout << bitset<8>(x) << endl; // print 8 low-order bits of x 
Cuestiones relacionadas