2011-08-28 10 views
7

Tôi bắt đầu đọc "Lập trình ngọc trai" ngày hôm nay và trong khi thực hiện nó tập thể dục tôi đi qua câu hỏi này "Làm thế nào bạn sẽ thực hiện bit bit của riêng bạn?". Khi tôi nhìn vào giải pháp đó là như thế này:Sử dụng Mặt nạ bit trong chương trình dưới đây từ Lập trình Pearls

#define BITSPERWORD 32 
#define SHIFT 5 
#define MASK 0x1F 
#define N 10000000 

int a[1 + N/BITSPERWORD]; 

void set(int i) { a[i >> SHIFT] |= (1 << (i & MASK)); 

Nơi tôi đang nhận được nhầm lẫn tại là tuyên bố này

1 << (i & MASK) 

thể ai đó hãy giải thích cho tôi những gì đang xảy ra ở đây?

Trả lời

4

Lưu ý rằng MASK được đặt sao cho có số bit thấp nhất là SHIFT, trong đó SHIFT chính xác là lô-ga-lô cơ sở 2 của BITSPERWORD.

Vì vậy, (i & MASK) sẽ chọn 5 bit thấp nhất là i, tương tự như phần còn lại sau khi chia cho 32 (chỉ xem xét cách lấy hai chữ số thấp nhất của số thập phân cho bạn phần còn lại sau khi chia cho 100 thí dụ). Điều này khiến số lượng các bit trong một từ chúng tôi quan tâm.

1 << (i & MASK)) (đó là, bằng cách này, một biểu , không phải là một tuyên bố ) bây giờ tạo ra một giá trị mà chính xác các bit chúng tôi đang quan tâm được thiết lập. Hợp nhất giá trị này vào từ bộ nhớ với |= sẽ thiết lập bit mong muốn của bit bit.

+0

Cảm ơn bạn đã trả lời Henning. Điều này có hợp lệ không nếu tôi thay thế '(i & MASK)' bằng '(i% 32)'? Nếu nó sẽ hợp lệ nhưng không thanh lịch thì bạn có thể làm sáng tỏ một số lý do tại sao 'i & MASK' được ưa thích hơn' i% 32'? Cảm ơn rất nhiều. – test123

+0

Có - 'i & MASK' và' i% 32' là điều tương tự miễn là bạn chắc chắn 'i' không tiêu cực. Các bitwise AND thường hiệu quả hơn một bộ phận với phần còn lại, và do đó đã trở thành sự lựa chọn truyền thống. Hoặc ít nhất nó được sử dụng để trở lại hiệu quả hơn khi trình biên dịch nơi ngu ngốc. Hôm nay, bạn có thể mong đợi một trình biên dịch tối ưu vừa phải để viết lại 'i% 32' thành' i & 31' trong ngữ cảnh này (hoặc có thể chứng minh rằng 'i' không âm, trong trường hợp viết lại luôn an toàn, hoặc nó có thể lý do rằng một kết quả tiêu cực sẽ kích hoạt hành vi không xác định trong sự thay đổi anyway). –

+0

Tuyệt. Cảm ơn rất nhiều vì lời giải thích. – test123

2

0x20 là 32, vì vậy i & 0x1F mất i modulo 32, sao cho bạn không bao giờ thay đổi 32 bit. Đây là một biện pháp bảo vệ bởi vì thay đổi bởi bất kỳ thứ gì không nhỏ hơn kích thước của kiểu là hành vi không xác định.

+0

Cảm ơn bạn đã trả lời Kerrek! – test123