2011-10-20 36 views
6

Có lẽ câu hỏi là đơn giản như vậy ...trên enum và Bitwise hoạt động

Có một định nghĩa enum:

enum uop_flags_enum { 
    FICOMP  = 0x001, 
    FLCOMP  = 0x002, 
    FFCOMP  = 0x004, 
    FMEM   = 0x008, 
    FLOAD   = 0x010, 
    FSTORE  = 0x020, 
    FCTRL   = 0x040, 
    FCALL   = 0x080, 
    FRET   = 0x100, 
    FCOND   = 0x200 
}; 

Một nơi nào đó trong các mã có:

if (uop->flags & FCTRL) 

Khi điều này điều kiện là đúng và khi nó không?

Trả lời

14

Cuối cùng, mã này đang kiểm tra xem một bit (cờ FCTRL) có được bật trong biến số uop->flags hay không.

Nhưng đây là một số giải thích:

Mặc nhiên, các mã if(X) kiểm tra cho X là một giá trị "true". Đối với số nguyên, 0 là giá trị "false" duy nhất và mọi thứ khác là "true".

Do đó mã của bạn là tương đương với:

if (0 != (uop->flags & FCTRL))

Bây giờ, có nghĩa là gì?

Toán tử & thực hiện "bitwise AND", nghĩa là mỗi bit của cạnh bên trái là ANDed với bit tương ứng ở phía bên tay phải.

Vì vậy, nếu chúng tôi đã viết ra hai toán hạng của chúng tôi ở dạng nhị phân:

uop->flags  1010 1010 (example) 

FCTRL   0100 0000 

Trong ví dụ này, nếu bạn thực hiện một "VÀ" trên mỗi cặp bit, bạn sẽ có được kết quả:

result   0000 0000 

Đánh giá sai, và thực sự trong ví dụ đó giá trị uop->flags không có cờ FCTRL được đặt.

Bây giờ đây là một ví dụ khác, nơi lá cờ thiết lập:

uop->flags  1110 1010 (example) 

FCTRL   0100 0000 

Kết quả ANDed tương ứng:

result   0100 0000 

Kết quả này không phải là zero, do đó "true", kích hoạt của bạn if tuyên bố.

1

Khi bit tương ứng với FCTRL (0x040) được đặt trong uop-> cờ, điều kiện là đúng. '&' là bitwise AND có hiệu lực che tất cả các bit nhưng được đặt bởi FCTRL.

+0

uop-> flags = 0x140 => là điều kiện đúng không? – mahmood

+0

có bởi vì kết quả của 0x140 & 0x040 là 0x040. – Lou

+0

Xem http://en.wikipedia.org/wiki/Bitwise_operation để biết thêm chi tiết về các thao tác bitwise. – Lou

5

Đây là một enum được sử dụng để xác định một số "cờ" cho một thao tác. Bạn có thể suy ra điều này bằng thực tế rằng mọi giá trị được xác định là một sức mạnh chính xác của hai, và vì điều này được biểu diễn bằng một bit ("cờ") của một giá trị.

Ưu điểm của loại hình này enum là bạn có thể kết hợp càng nhiều của các cờ như bạn muốn bằng cách sử dụng bitwise OR:

uop->flags = FMEM | FLOAD | FRET; // sets the three corresponding flags 

Điều kiện bạn đưa ra, trong đó sử dụng bitwise AND

uop->flags & FCTRL 

là đúng nếu và chỉ khi cờ FCTRL được đặt, tức là khi bit thứ 7 của uop->flags được đặt. Điều này là do FCTRL == 0x040 == nhị phân 01000000.

+0

Tôi nên làm gì nếu tôi muốn kiểm tra xem FRET có được đặt không? – mahmood

+0

@mahmood: 'if (uop-> flags & FRET) {/ * FRET được đặt * /}' – Jon

0

Điều kiện là đúng khi bit được đặt. 0x40 là 1000000, vì vậy khi bit thứ 7 trong flags được đặt - nó sẽ là đúng.

0

Khi kiểu liệt kê đang sử dụng vị trí của các chữ số nhị phân (tức là các đơn vị, 2, 4, 8, 16 vv) và thao tác thực hiện một logic và. Nếu vị trí bit đó được thiết lập, giá trị sẽ không bằng 0 (true) nếu không nó sẽ là false.

0

Trong trường hợp này, mỗi mục enum tiếp theo được dịch chuyển 1 bit sang trái, do đó, kiểm tra xem cờ nào được đặt bằng cách chỉ kiểm tra xem variable & flag == true có hợp pháp không. Tuy nhiên, nếu chúng ta muốn đặt mẫu cờ nhiều bit thì sao? Ví dụ:

enum { 
    #ifdef __GNUC__ // cool in GCC we can use binary constants 
     myFlag = 0b1010 
    #else   // otherwise fallback into integral constant mode 
     myFlag = 10 
    #endif 
} 

khi kiểm tra xem biến X của chúng tôi có gắn cờ này chưa? Chúng tôi không thể chỉ làm X & myFlag == true, vì ví dụ: 0b1000 & myFlag == true0b0010 & myFlag == true - nhưng không phải 0b1000 cũng không 0b0010 có hai bit TWO được đặt! Vì lý do này, tôi muốn kiểm tra đầy đủ bitmask để cho phép xác định các mẫu nhiều bit trong enum:

#define IS_BIT_MASK_SET(variable,flag) ((variable & flag) == flag) 

hth!

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