2010-04-21 7 views
13

Làm cách nào để chuyển đổi một số nguyên sang biểu diễn bit của nó. Tôi muốn lấy một số nguyên và trả về một vectơ chứa 1 và 0 của biểu diễn bit của số nguyên.Chuyển đổi số nguyên thành một bit đại diện

Tôi đang có một thời gian để tự mình làm điều này vì vậy tôi nghĩ tôi sẽ hỏi xem có chức năng thư viện có sẵn có thể giúp ích hay không.

+2

Tôi nghĩ bạn có nghĩa là đại diện _bit_. – fbrereto

+5

Đây có phải là bài tập về nhà không? – fbrereto

+0

Cho rằng một số nguyên là một kích thước cố định, tại sao không chỉ sử dụng một mảng đơn giản? –

Trả lời

13

Không hoạt động với từ khóa phủ định.

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

Rất cám ơn! :) Bây giờ tôi có thể triển khai thuật toán theo cách tôi dự định ban đầu. : D – bobber205

+3

Hoặc 'do ret.push_back (x & 1) trong khi (x >> = 1);' - phiên bản này trả về một bit không cho đầu vào số không. – Potatoswatter

0

nguyên tồi tệ nhất trên thế giới để bit byte Chuyển đổi:

#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

Ồ. Tôi tự hỏi tại sao Perl nổi danh vì không thể hiểu nổi =) – maerics

+0

Chắc chắn xứng đáng là một không gian độc quyền @ codinghorror. – jweyrich

+0

Đây là một ví dụ từ đời thực? – Potatoswatter

2

Đây là một phiên bản làm việc với số âm:

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

Chuỗi có thể, tất nhiên, được thay thế bởi một vectơ hoặc được lập chỉ mục cho các giá trị bit.

3

Sửa đổi câu trả lời của DCP. Hành vi được thực hiện được xác định cho các giá trị âm của t. Nó cung cấp tất cả các bit, ngay cả các số không đứng đầu. Tiêu chuẩn hãy cẩn thận liên quan đến việc sử dụng std::vector<bool> và nó không phải là một container thích hợp.

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

Và phiên bản [có thể] cũng hoạt động với các giá trị dấu phẩy động. Và có thể các loại POD khác. Tôi đã không thực sự thử nghiệm điều này cả. Nó có thể làm việc tốt hơn cho các giá trị tiêu cực, hoặc nó có thể làm việc tồi tệ hơn. Tôi đã không suy nghĩ nhiều về nó.

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 có thể xuất hiện trong giây phút thứ hai, huh? Oh well. –

1

Trả về chuỗi thay vì vectơ nhưng có thể dễ dàng thay đổi.

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

Không quá khó để giải quyết bằng một lớp lót, nhưng thực tế là giải pháp thư viện chuẩn.

#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 thậm chí còn dễ dàng hơn!

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

Đây là một trong những góc kỳ lạ hơn của thư viện. Có lẽ thực sự những gì họ đang lái xe là serialization.

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