2010-06-29 8 views
7

Tôi nghĩ tôi có thể đã ngủ trong lớp CS khi họ nói về Bit Positions, vì vậy tôi hy vọng ai đó có thể giúp một tay.Tìm vị trí bit trong số nguyên 32 bit chưa ký

Tôi có một số nguyên 32-bit unsigned (Cho phép sử dụng giá trị: 28)

Theo một số tài liệu tôi sẽ kết thúc, giá trị của các số nguyên chứa cờ xác định những điều khác nhau.

Vị trí bit trong cờ được đánh số từ 1 (thứ tự thấp) đến 32 (thứ tự cao). Tất cả các bit cờ không xác định được đặt trước và phải được đặt thành 0.

Tôi có Bảng hiển thị ý nghĩa của cờ, với ý nghĩa đối với các số 1-10.

Tôi hy vọng rằng ai đó có thể thử và giải thích cho tôi ý nghĩa của điều này và cách tìm giá trị "cờ" từ một số như, 28, dựa trên vị trí bit.

Cảm ơn

Trả lời

8

2 8 chuyển đổi thành 11100 dưới dạng nhị phân. Điều đó có nghĩa là các bit 1 và 2 không được thiết lập và các bit 3, 4 và 5 được đặt.

Một vài điểm: thứ nhất, bất cứ ai thực sự quen với C sẽ thường bắt đầu đánh số 0, không 1. Thứ hai, bạn có thể kiểm tra cờ cá nhân với Bitwise và nhà điều hành (&), như trong:

#define flag1 1 // 1 = 00 0001 
#define flag2 2 // 2 = 00 0010 
#define flag3 4 // 4 = 00 0100 
#define flag4 8 // 8 = 00 1000 
#define flag5 16 // 16 = 01 0000 
#define flag6 32 // 32 = 10 0000 

if (myvalue & flag1) 
    // flag1 was set 

if (myvalue & flag4) 
    // flag4 was set 

v.v. Bạn cũng có thể kiểm tra bit được thiết lập trong một vòng lặp:

#include <stdio.h> 

int main() { 
    int myvalue = 28; 
    int i, iter; 

    for (i=1, iter=1; i<256; i<<=1, iter++) 
     if (myvalue & i) 
      printf("Flag: %d set\n", iter); 
    return 0; 
} 

nên in:

Flag: 3 set 
Flag: 4 set 
Flag: 5 set 
+0

Jerry @ invaliddata của, phần đầu tiên của bạn về các giá trị nhị phân có ý nghĩa, tuy nhiên tôi là một chút con hợp nhất về mã bạn đã đăng ... Bạn cũng có các mục flag1, flag2, etc, cũng đề cập đến điều gì? Khi tôi đặt những gì bạn có, tôi nhận được đầu ra mà 4 và 8 được thiết lập. Không chắc chắn những gì đang đề cập đến kể từ trên, chúng tôi nói bit 3, 4, và 5 đã được thiết lập – kdbdallas

+0

@ kdbdallas: Tôi đã thêm một số ý kiến ​​cho mã mà tôi hy vọng làm cho ý nghĩa của cờ một chút rõ ràng hơn. –

0

Giả sử flags là unsigned ...

int flag_num = 1; 
while (flags != 0) 
{ 
    if ((flags&1) != 0) 
    { 
     printf("Flag %d set\n", flags); 
    } 
    flags >>= 1; 
    flag_num += 1; 
} 

Nếu flags được ký bạn nên thay thế

flags >>= 1; 

với

flags = (flags >> 1) & 0x7fffffff; 
3

Để có được một int với giá trị 0 hoặc 1 đại diện chỉ bit thứ n từ đó số nguyên, sử dụng :

int bitN = (value >> n) & 1; 

Nhưng đó không phải thường là điều bạn muốn làm. Một thành ngữ phổ biến hơn là thế này:

int bitN = value & (1 << n); 

Trong trường hợp này bitN sẽ 0 nếu bit thứ n không được thiết lập, và không trong các trường hợp đó các bit thứ n được thiết lập. (Cụ thể, nó sẽ là bất cứ giá trị nào xuất hiện chỉ với bộ bit thứ n.)

8

Thay vì lặp qua mỗi bit duy nhất, bạn có thể thay vì lặp qua chỉ các bit bộ, có thể nhanh hơn nếu bạn mong đợi bit để được thưa thớt thiết lập:

Giả lĩnh vực bit là trong (nguyên vô hướng) trường biến.

while (field){ 
    temp = field & -field; //extract least significant bit on a 2s complement machine 
    field ^= temp; // toggle the bit off 
    //now you could have a switch statement or bunch of conditionals to test temp 
    //or get the index of the bit and index into a jump table, etc. 
} 

Hoạt động khá tốt khi trường bit không bị giới hạn kích thước của một loại dữ liệu, nhưng có thể có kích thước tùy ý. Trong trường hợp đó, bạn có thể trích xuất 32 (hoặc bất kỳ kích thước đăng ký của bạn là) bit tại một thời điểm, kiểm tra nó so với 0, và sau đó chuyển sang từ tiếp theo.

0

Sử dụng một hàm log, với cơ sở 2. Trong python, đó sẽ như thế nào:

import math 

position = math.log(value, 2) 

Nếu vị trí không phải là một số nguyên, sau đó hơn 1 chút được thiết lập để 1.

0

Một biến thể nhẹ answer-

unsigned int tmp_bitmap = x;   
while (tmp_bitmap > 0) { 
    int next_psn = __builtin_ffs(tmp_bitmap) - 1; 
    tmp_bitmap &= (tmp_bitmap-1); 
    printf("Flag: %d set\n", next_psn); 
} 
0
// You can check the bit set positions of 32 bit integer. 
// That's why the check is added "i != 0 && i <= val" to iterate till 
// the end bit position. 
    void find_bit_pos(unsigned int val) { 
      unsigned int i; 
      int bit_pos; 
      printf("%u::\n", val); 
      for(i = 1, bit_pos = 1; i != 0 && i <= val; i <<= 1, bit_pos++) { 
        if(val & i) 
          printf("set bit pos: %d\n", bit_pos); 
      } 
    }