2013-03-06 74 views
10

Tôi đang gặp một chút rắc rối khi lấy n bit từ một byte.Lấy n bit từ một byte

Tôi có số nguyên không dấu. Giả sử số của chúng tôi trong hex là 0x2A, là số thập phân 42. Trong nhị phân nó trông như thế này: 0010 1010. Làm thế nào tôi sẽ lấy 5 bit đầu tiên là 00101 và 3 bit tiếp theo là 010, và đặt chúng vào các số nguyên riêng biệt?

Nếu có ai có thể giúp tôi điều đó thật tuyệt! Tôi biết cách trích xuất từ ​​một byte đơn giản là làm

int x = (number >> (8*n)) & 0xff // n being the # byte 

mà tôi thấy trên một bài đăng khác trên ngăn xếp tràn, nhưng tôi không chắc chắn cách lấy các bit riêng ra khỏi byte. Nếu ai đó có thể giúp tôi, điều đó thật tuyệt! Cảm ơn!

+0

bit 5 (MSB) đầu tiên là 42 là 00000 vì int luôn hơn 1 byte. Ngoài ra, không có thứ như số nguyên không dấu có dạng thập phân của hex. 'int a = 0x2A;' cũng giống như viết 'int a = 42;' – user93353

Trả lời

14

Số nguyên được biểu diễn bên trong máy dưới dạng chuỗi bit; may mắn cho con người chúng ta, ngôn ngữ lập trình cung cấp một cơ chế để cho chúng ta thấy những con số này theo dạng thập phân (hoặc thập lục phân), nhưng điều đó không làm thay đổi biểu diễn bên trong của chúng.

Bạn nên sửa đổi các nhà khai thác Bitwise &, |, ^~ cũng như các nhà khai thác dịch chuyển <<>>, mà sẽ giúp bạn hiểu làm thế nào để giải quyết vấn đề như thế này.

3 bit cuối cùng của số nguyên là:

x & 0x7 

Năm bit bắt đầu từ bit tám cuối cùng là:

x >> 3 // all but the last three bits 
    & 0x1F // the last five bits. 
+0

Làm thế nào để so sánh hiệu năng này với việc lưu trữ hai phần tử phụ dưới dạng hai số nguyên 32 bit? Việc khai thác sẽ mất một thời gian, nhưng có 32 hoạt động chậm hơn không? – Kammeot

+0

@InspiredOne: Các câu hỏi như thế không thể trả lời chính xác trong tóm tắt, nhưng rõ ràng là nó cải thiện việc sử dụng bộ nhớ (bởi hệ số 8 liên quan đến hai số nguyên 32 bit, hoặc bởi một hệ số hai liên quan đến hai byte) cải thiện hiệu suất bộ nhớ cache, thông lượng bộ nhớ và băng thông nếu có liên quan (thời gian truyền hoặc bộ nhớ phụ). Vì chi phí CPU là tầm thường so với bất kỳ yếu tố nào trong số này, dữ liệu nén thường sẽ được cung cấp nhanh hơn nếu bạn cần nhiều phiên bản; nó không đáng làm cho một cặp biến (nhưng nó cũng không gây hại nhiều). – rici

1

chỉ cần loại bỏ 8 * trong mã của bạn.

int input = 42; 
int high3 = input >> 5; 
int low5 = input & (32 - 1); // 32 = 2^5 
bool isBit3On = input & 4; // 4 = 2^(3-1) 
1

int x = (number >> 3) & 0x1f;

sẽ cung cấp cho bạn một số nguyên nơi 5 bit cuối cùng là các bit 8-4 của number và số không trong các bit khác.

Tương tự,

int y = number & 0x7;

sẽ cung cấp cho bạn một số nguyên với 3 bit cuối cùng thiết lập 3 bit cuối cùng của number và zeros trong phần còn lại.

7

Giả sử bạn muốn hi bit từ trên cùng và lo bit từ dưới cùng. (5 và 3 trong ví dụ của bạn)

top = (n >> lo) & ((1 << hi) - 1) 
bottom = n & ((1 << lo) - 1) 

Giải thích:

Đối với đầu, đầu tiên thoát khỏi các bit thấp (shift bên phải), sau đó mặt nạ còn lại với một "tất cả những" mặt nạ (nếu bạn có số nhị phân như 0010000, hãy trừ một kết quả 0001111 - cùng số 1 s khi bạn có số 0 -s trong số ban đầu).

Đối với phần dưới cùng, chỉ cần không quan tâm đến việc dịch chuyển ban đầu.

top = (42 >> 3) & ((1 << 5) - 1) = 5 & (32 - 1) = 5 = 00101b 
bottom = 42 & ((1 << 3) - 1) = 42 & (8 - 1) = 2 = 010b 
12

"grabbing" bộ phận của một kiểu số nguyên trong C làm việc như thế này:

  1. Bạn thay đổi các bit bạn muốn vị trí thấp nhất.
  2. Bạn sử dụng & để che dấu các bit bạn muốn - những người có nghĩa là "bản sao bit này", số không có nghĩa là "bỏ qua"

Vì vậy, trong bạn chẳng hạn. Hãy nói rằng chúng tôi có một số int x = 42;

đầu tiên 5 bit:

(x >> 3) & ((1 << 5)-1); 

hoặc

(x >> 3) & 31; 

Để lấy thấp hơn ba bit:

(x >> 0) & ((1 << 3)-1) 

hay:

x & 7; 
2

Bạn có thể sử dụng bitfield cho mục này. Bitfield là các cấu trúc đặc biệt, nơi bạn có thể chỉ định các biến theo bit.

typedef struct { 
    unsigned char a:5; 
    unsigned char b:3; 
} my_bit_t; 

unsigned char c = 0x42; 
my_bit_t * n = &c; 
int first = n->a; 
int sec = n->b; 

lĩnh vực Bit được mô tả một cách chi tiết hơn tại http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION001320000000000000000

Nét duyên dáng của các lĩnh vực bit là, bạn không phải đối phó với những hoạt động thay đổi, vv Các ký hiệu là khá dễ dàng. Như thường lệ với thao tác bit, có một vấn đề về tính di động.

Các vấn đề liên quan