2017-08-05 366 views
0

假设我有两个变量,即只使用6位:Golang中如何计算字节中有多少位字节?

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) ...


但我不认为这是我们的最佳解决方案情况,我不认为这需要一个循环,因为它我在这里。

有更好的选择(在性能方面)来计算有多少1有六位?

+1

转到1.9(以2017年八月公布 - 预发行是没有可用的)将推出https://beta.golang.org/pkg/math/位/#OnesCount和其他位操作功能。正如我们可以从[documentation](https://beta.golang.org/doc/go1.9#math-bits)中看到的那样,它将根据架构进行优化。 –

回答

2

鉴于输入是单字节可能是一个查找表是最好的选择...只需要256个字节,你会得到这样的代码

var count = bitcount[input]; 
1

鉴于此功能将在包可用math/bits在下一个Go版本(今年八月的1.9)中,这里是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。并且特别针对你的问题:8bits

func OnesCount8(x uint8) int { 
    return int(pop8tab[x]) 
} 
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 
} 

您必须进行基准测试,看看它是否比最简单的查找表更快。