问题
I have following byte slice which from which i need to extract bits and place them in a []int as i intend to fetch individual bit values later. I am having a hard time figuring out how to do that.
below is my code
data := []byte{3 255}//binary representation is for 3 and 255 is 00000011 11111111
what i need is a slice of bits -- > [0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1]
What i tried
- I tried converting byte slice to Uint16 with BigEndian and then tried to use
strconv.FormatUint
but that fails with errorpanic: runtime error: index out of range
- Saw many examples that simple output bit representation of number using
fmt.Printf
function but that is not useful for me as i need a int slice for further bit value access.
Do i need to use bit shift operators here ? Any help will be greatly appreciated.
回答1:
One way is to loop over the bytes, and use a 2nd loop to shift the byte values bit-by-bit and test for the bits with a bitmask. And add the result to the output slice.
Here's an implementation of it:
func bits(bs []byte) []int {
r := make([]int, len(bs)*8)
for i, b := range bs {
for j := 0; j < 8; j++ {
r[i*8+j] = int(b >> uint(7-j) & 0x01)
}
}
return r
}
Testing it:
fmt.Println(bits([]byte{3, 255}))
Output (try it on the Go Playground):
[0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1]
回答2:
Using the bits
package provides a fairly straightforward solution.
func bitsToBits(data []byte) (st []int) {
st = make([]int, len(data)*8) // Performance x 2 as no append occurs.
for i, d := range data {
for j := 0; j < 8; j++ {
if bits.LeadingZeros8(d) == 0 {
// No leading 0 means that it is a 1
st[i*8+j] = 1
} else {
st[i*8+j] = 0
}
d = d << 1
}
}
return
}
Performance is comparable to similar solutions.
来源:https://stackoverflow.com/questions/52811744/extract-bits-into-a-int-slice-from-byte-slice