Từ http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
unsigned int v; // count bits set in this (32-bit value)
unsigned int c; // store the total here
c = v - ((v >> 1) & 0x55555555);
c = ((c >> 2) & 0x33333333) + (c & 0x33333333);
c = ((c >> 4) + c) & 0x0F0F0F0F;
c = ((c >> 8) + c) & 0x00FF00FF;
c = ((c >> 16) + c) & 0x0000FFFF;
Edit: Phải thừa nhận rằng đó là một chút tối ưu hóa mà làm cho nó khó khăn hơn để đọc. Nó dễ dàng hơn để đọc như:
c = (v & 0x55555555) + ((v >> 1) & 0x55555555);
c = (c & 0x33333333) + ((c >> 2) & 0x33333333);
c = (c & 0x0F0F0F0F) + ((c >> 4) & 0x0F0F0F0F);
c = (c & 0x00FF00FF) + ((c >> 8) & 0x00FF00FF);
c = (c & 0x0000FFFF) + ((c >> 16)& 0x0000FFFF);
Mỗi bước của những năm, thêm bit láng giềng với nhau trong nhóm 1, sau đó 2, sau đó 4, vv Phương pháp này có trụ sở tại chia để trị.
Trong bước đầu tiên, chúng tôi cộng các bit 0 và 1 và đặt kết quả trong phân đoạn bit 2 0-1, thêm bit 2 và 3 và đặt kết quả trong phân đoạn hai bit 2-3 ... Trong bước thứ hai, chúng ta thêm hai bit 0-1 và 2-3 lại với nhau và đặt kết quả trong 4-bit 0-3, cộng hai bit 4-5 và 6-7 lại với nhau và đặt kết quả trong bốn-bit 4-7 vv ...
Ví dụ:
So if I have number 395 in binary 0000000110001011 (0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 1)
After the first step I have: 0000000101000110 (0+0 0+0 0+0 0+1 1+0 0+0 1+0 1+1) = 00 00 00 01 01 00 01 10
In the second step I have: 0000000100010011 (00+00 00+01 01+00 01+10) = 0000 0001 0001 0011
In the fourth step I have: 0000000100000100 ( 0000+0001 0001+0011 ) = 00000001 00000100
In the last step I have: 0000000000000101 ( 00000001+00000100 )
tương đương với 5, đó là kết quả chính xác
Cảm ơn bạn. Tôi xin lỗi, tôi không hoàn toàn hiểu tại sao điều này hoạt động. Bạn có thể giải thích – JAM
Tôi đã thêm một lời giải thích, phải mất một thời gian bởi vì tôi đã phải tìm ra chính mình những gì đang xảy ra. +1 cho câu hỏi của bạn vì buộc tôi phải hiểu: P – iniju
Ngoài ra, hãy xem câu trả lời này, bước này thực hiện từng bước: http://stackoverflow.com/a/15979139/31818 – seh