Преобразование целого числа в битовое представление - PullRequest
13 голосов
/ 22 апреля 2010

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

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

Ответы [ 6 ]

16 голосов
/ 22 апреля 2010

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

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;
}
6 голосов
/ 22 апреля 2010

Это не слишком сложно решить с помощью одной строки, но на самом деле есть решение стандартной библиотеки.

#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
3 голосов
/ 22 апреля 2010

Модификация ответа 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;
}
2 голосов
/ 22 апреля 2010

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

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

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

1 голос
/ 22 апреля 2010

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

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;
}
0 голосов
/ 22 апреля 2010

Наихудшее в мире целочисленное значение в битах в виде байтов:

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