2010-04-21 4 views
13

Как преобразовать целое число в его представление битов. Я хочу взять целое число и вернуть вектор, содержащий 1 и 0 двоичного представления целого числа.Преобразование целого числа в представление битов

У меня есть время, пытаясь сделать это самостоятельно, поэтому я подумал, что попрошу посмотреть, есть ли встроенная функция библиотеки, которая могла бы помочь.

+2

Я думаю, вы имеете в виду _bit_ представительство. – fbrereto

+5

Это домашнее задание? – fbrereto

+0

Учитывая, что целое число является фиксированным, почему бы просто не использовать простой массив? –

ответ

13

Не работает с негативами.

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

Большое спасибо! :) Теперь я могу реализовать алгоритм так, как я изначально планировал. : D – bobber205

+3

Или 'do ret.push_back (x & 1) while (x >> = 1);' - эта версия возвращает нулевой бит для нулевого ввода. – Potatoswatter

0

худшее число в мире биту в байтах преобразователя:

#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

Ничего себе. Интересно, почему Perl получил репутацию непонятного =) – maerics

+0

Определенно заслуживает эксклюзивного space @ codinghorror. – jweyrich

+0

Это пример из реальной жизни? – Potatoswatter

2

Вот версия, которая работает с отрицательными числами:

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

Строка может, конечно, быть заменен вектором или индексированным для значений бит.

3

Модификация ответа DCP. Поведение - это реализация, определенная для отрицательных значений t. Он предоставляет все биты, даже ведущие нули. Стандартные оговорки, связанные с использованием std::vector<bool>, и не являются надлежащим контейнером.

#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; 
} 

И версия, которая [могла бы] работать со значениями с плавающей запятой. И, возможно, другие типы POD. Я вообще не тестировал это. Это может работать лучше для отрицательных значений, иначе это может ухудшиться. Я не задумывался над этим.

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, вероятно, всплывает в этом втором, да? Ну что ж. –

1

Возвращает строку вместо вектора, но ее можно легко изменить.

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

Это не так сложно решить с помощью одного вкладыша, но на самом деле существует стандартная библиотека.

#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 даже упрощает!

#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()); 
} 

Это один из самых причудливых уголков библиотеки. Возможно, действительно, на что они ехали, была сериализация.

cout << bitset<8>(x) << endl; // print 8 low-order bits of x 
Смежные вопросы