这是一个版本,它一次通过 4 个字节的数组,需要 10 次迭代:
uint32_t *arr1_int = (uint32_t*) arr1;
uint32_t *arr2_int = (uint32_t*) arr2;
int i;
int bits_set = 0;
for (i = 0; i < 10; i++) {
uint32_t v = arr1_int[i] & arr2_int[i];
/* http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel */
v = v - ((v >> 1) & 0x55555555);
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
bits_set += ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
}
使用现代 CPU,使用编译器内在函数,您可以更快地做到这一点。例如在带有 Visual C++ 的 64 位 CPU 上:
#include <intrin.h>
__int64 *arr1_int = (__int64*) arr1;
__int64 *arr2_int = (__int64*) arr2;
int bits_set = 0;
/* 40 / 8 bytes == 5 iterations */
bits_set += __popcnt64(*arr1_int++ & *arr2_int++);
bits_set += __popcnt64(*arr1_int++ & *arr2_int++);
bits_set += __popcnt64(*arr1_int++ & *arr2_int++);
bits_set += __popcnt64(*arr1_int++ & *arr2_int++);
bits_set += __popcnt64(*arr1_int++ & *arr2_int++);
但这一切都考虑到了性能,如果你只是想要一些可读的代码,肯定会符合 Rob 的建议。