【问题标题】:Extract bits into a int slice from byte slice从字节切片中提取位到 int 切片中
【发布时间】:2018-10-15 07:31:25
【问题描述】:

我有以下字节片,我需要从中提取位并将它们放在 []int 中,因为我打算稍后获取单个位值。我很难弄清楚如何做到这一点。

下面是我的代码

data := []byte{3 255}//binary representation is for 3 and 255 is 00000011 11111111

我需要的是一片比特 --> [0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1]

我尝试了什么

  • 我尝试使用 BigEndian 将字节切片转换为 Uint16,然后尝试使用 strconv.FormatUint,但失败并出现错误 panic: runtime error: index out of range
  • 看到了许多使用fmt.Printf 函数简单输出位表示数字的示例,但这对我没有用,因为我需要一个 int 切片来进一步访问位值。

我需要在这里使用位移运算符吗?任何帮助将不胜感激。

【问题讨论】:

    标签: arrays go slice bit endianness


    【解决方案1】:

    一种方法是遍历字节,并使用第二个循环逐位移动字节值并使用位掩码测试位。并将结果添加到输出切片中。

    这是它的一个实现:

    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
    }
    

    测试它:

    fmt.Println(bits([]byte{3, 255}))
    

    输出(在Go Playground 上试试):

    [0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1]
    

    【讨论】:

      【解决方案2】:

      使用bits 包提供了一个相当简单的解决方案。

      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
      }
      

      性能与similar solutions相当。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-21
        • 2020-10-24
        • 2019-05-18
        • 1970-01-01
        • 2022-01-19
        • 1970-01-01
        • 2011-05-30
        • 1970-01-01
        相关资源
        最近更新 更多