int count_ones_v1(unsigned int n) {
int c = 0;
while (n) {
if (n & 1) c++;
n >>= 1;
}
return c;
}
int count_ones_v2(unsigned int n) {
int c = 0;
while (n) {
n &= (n - 1); // 清除最低位 1
c++;
}
return c;
}
原理:n-1 翻轉最低位 1 及其後所有位,& 清除該 1。迴圈次數 = 1 的個數。
// 256 字節查表
static const unsigned char table[256] = {0,1,1,2,1,2,2,3,...};
int count_ones_v3(unsigned int n) {
return table[n & 0xFF] +
table[(n>>8) & 0xFF] +
table[(n>>16) & 0xFF] +
table[n>>24];
}
// 編譯器內建 (最佳實戰)
int count_ones_builtin(unsigned int n) {
return __builtin_popcount(n); // GCC/Clang
// MSVC: __popcnt(n) (需 )
}
| 方法 | 相對時間 | 備註 |
|---|---|---|
| 逐位檢查 | 1.0x | 基準 |
| Kernighan | 0.3x | 稀疏 1 極快 |
| 查表 8bit | 0.15x | 固定 4 次查表 |
| __builtin_popcount | 0.02x | 單指令 POPCNT |
__builtin_popcount / C23 stdc_popcount。