《CSAPP》上的题目,略有难度。
问题来源
限制
- 编程语言:C
- 可用操作符:! ~ & ^ | + << >>
- 最大操作步数:40
- 最大操作数:255
思路
获取2位二进制数内”1”个数
设该数为x
,则答案易得为(x & 01) + ((x >> 1) & 01)
获取4位二进制数内”1”个数
设该数为x
可以先把每两位的”1”个数求出,再加起来。
y = (x & 0101) + ((x >> 1) & 0101)
count = (y & 0011) + ((y >> 10) & 0011)
获取8位二进制数内”1”个数
设该数为x
把每两位的”1”个数求出,存储在每两位中。再把每四位的”1”个数求出,存储在每四位中。最后加起来。
y = (x & 01010101) + ((x >> 1) & 01010101)
z = (y & 00110011) + ((y >> 10) & 00110011)
count = (z & 00001111) + ((z >> 1000) & 00001111)
···
···
···
获取32位二进制数内”1”个数
- 每两位数存”1”的个数:
storePer2 = (0x???????? & 0x55555555) + ((0x???????? >> 1) & 0x55555555)
- 每四位数存”1”的个数:
storePer4 = (storePer2 & 0x33333333) + ((storePer2 >> 2) & 0x33333333)
- 每八位数存”1”的个数:
storePer8 = (storePer4 & 0x0f0f0f0f) + ((storePer4 >> 4) & 0x0f0f0f0f)
- 每十六位数存”1”的个数:
storePer16 = (storePer8 & 0x00ff00ff) + ((storePer8 >> 8) & 0x00ff00ff)
- 用32位数来存储结果:
count = (storePer16 & 0x0000ffff) + ((storePer16 >> 16) & 0x0000ffff)
代码
|
|