2017-08-05 365 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 
} 

您必須進行基準測試,看看它是否比最簡單的查找表更快。