# g10guang/g10guang.github.io

Switch branches/tags
Nothing to show
Fetching contributors…
Cannot retrieve contributors at this time
132 lines (96 sloc) 3.87 KB
layout title date categories
post
64位整数中有多少个1
2018-09-04 09:00:05 +0800

# Main

C 语言在不同平台上数据长度有所差异，我测试机器是 64 位：

```printf("%lu %lu %lu\n", sizeof(unsigned int), sizeof(unsigned long), sizeof(unsigned long long));
// output: 4 8 8```

C 语言中的强制类型转换，比如 unsigned int 与 int 之间的转换，采用二进制不变方式，也就是改变解析的方式，对于编译器来说就是拷贝一块内快。比如：

```int x = -1; // 位模式：11111111 11111111 11111111 11111111
unsigned int y = (unsigned int)x; // 位模式：11111111 11111111 11111111 11111111，也就是 y == 2 ^ 32 - 1 == 4294967295
printf("%u", y);
// output: 4294967295```

```unsigned long long y = 0xffffffffffffffff;
int x = y; // 位模式：11111111 11111111 11111111 11111111
printf("%d\n", x);
// output: -1```

## 暴力破解

```unsigned int counter(unsigned long long n)
{
unsigned int cnt = 0;
while (n)
{
if (n & 1) cnt += 1;
n >>= 1;
}
return cnt;
}```

## 借助数学

```unsigned int counter(unsigned long long n)
{
unsigned int cnt = 0;
while (n)
{
cnt += 1;
// 去除最低位的 1
n &= n - 1;
}
return cnt;
}```

## 查表法

```static unsigned int table[255];

void init()
{
for (unsigned int i = 0; i <= 0xff; ++i)
{
table[i] = table[i & (i - 1)] + 1;
}
}

unsigned int counter(unsigned long long n)
{
unsigned int cnt = 0;
while (n)
{
cnt += table[(n & 0xff)];
n >>= 8;
}
return cnt;
}```

``````cache size	: 6144 KB
``````