【问题标题】:binary.Uvarint got wrong int value than expectedbinary.Uvarint 得到错误的 int 值而不是预期
【发布时间】:2014-02-18 19:32:40
【问题描述】:

我有一个长度为 4 的切片存储了一个这样的 int 值:

[159 124 0 0]

然后我尝试了val, encodeBytes := binary.Uvarint(slice),但是错了val

val = 15903, encodebytes = 2

正确的val应该是31903,有什么问题?

代码如下:

http://play.golang.org/p/kvhu4fNOag

【问题讨论】:

    标签: go


    【解决方案1】:

    根据二进制包文档,用于解释字节序列的编码是available here。它指定字节被解释为:

    varint 中的每个字节,除了最后一个字节,都有最重要的 bit (msb) set——这表明还有更多字节要到来。 每个字节的低 7 位用于存储二进制补码 以 7 位为一组表示数字,最低有效 先分组。

    [159 124 0 0] 的二进制表示为:

    1001  1111 , 0111 1100 , 0000  0000, 0000 0000
    

    第一个字节的最高有效位 (MSB) 已设置,因此第二个字节也将被解释。第二个字节 MSB 未设置,因此忽略其余字节。

    通过删除字节的 MSB 来解释我们得到的位:

    001 1111 , 111 1100 
    

    这两个组然后在被解释为数字之前被反转:

    111 1100 , 001 1111
    
    concatenated:
    0011 1110 0001 1111
    

    将其转换回十进制我们得到:

    1 + 2 +4 + 8 + 16 + 0 + 0 + 0 + 0 + 512 + 1024 + 2048 + 4096 + 8192 = 15903
    

    正如 James 和 peterSO 的帖子所表明的那样,您可能想改用 binary.LittleEndian.Uint32

    【讨论】:

      【解决方案2】:

      例如,

      package main
      
      import (
          "encoding/binary"
          "fmt"
      )
      
      func main() {
          bytes := []byte{159, 124, 0, 0}
          integer := int(binary.LittleEndian.Uint32(bytes))
          fmt.Println(bytes, integer)
      }
      

      输出:

      [159 124 0 0] 31903
      

      【讨论】:

        【解决方案3】:

        从预期的结果来看,听起来您正在尝试解码一个小端序的 32 位整数。 binary.Uvarint 函数不适合这项工作,因为它解码了 Protocol Buffers 规范使用的可变长度整数编码。

        请尝试使用binary.LittleEndian.Uint32():

        val := binary.LittleEndian.Uint32(slice)
        

        【讨论】:

          猜你喜欢
          • 2010-09-24
          • 2019-03-28
          • 2020-05-11
          • 2017-12-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-29
          • 1970-01-01
          • 2015-07-18
          相关资源
          最近更新 更多