假设我有两个变量,只使用6位:
var a byte = 31 // 00011111
var b byte = 50 // 00110010
第一个(a
)比b
多一位,但b
当然大于a
,因此无法使用a > b
。
为了实现我的需要,我做了一个循环:
func countOneBits(byt byte) int {
var counter int
var divider byte
for divider = 32; divider >= 1; divider >>= 1 {
if byt & divider == divider {
counter++
}
}
return counter
}
This works,我可以使用countOneBits(a) > countOneBits(b)
...
但我不认为这是这种情况的最佳解决方案,我不认为这需要一个循环因为它我就在这里。
有更好的替代方案(在性能方面)来计算6位中有多少1
?
答案 0 :(得分:2)
鉴于输入是单个字节,可能是查找表是最好的选择...只需要256个字节,你得到像
这样的代码var count = bitcount[input];
答案 1 :(得分:1)
鉴于此函数将在下一个Go版本(今年8月的1.9)中的包math/bits
中可用,这里是32位整数的代码。
// OnesCount32 returns the number of one bits ("population count") in x.
func OnesCount32(x uint32) int {
return int(pop8tab[x>>24] + pop8tab[x>>16&0xff] + pop8tab[x>>8&0xff] + pop8tab[x&0xff])
}
pop8tab
的定义here。特别是你的问题:8位
func OnesCount8(x uint8) int {
return int(pop8tab[x])
}
答案 2 :(得分:1)
也可以使用二进制运算来计数位。请参阅此bit twiddling hacks。
func bitSetCount(v byte) byte {
v = (v & 0x55) + ((v>>1) & 0x55)
v = (v & 0x33) + ((v>>2) & 0x33)
return (v + (v>>4)) & 0xF
}
你必须进行基准测试,看看它是否比最容易实现的查找表更快。
答案 3 :(得分:1)
有POPCNT golang版本: