binary.Uvarint的int值比预期的错误

时间:2014-02-18 09:49:48

标签: go

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

[159 124 0 0]

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

val = 15903, encodebytes = 2

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

以下是代码:

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

3 个答案:

答案 0 :(得分:1)

例如,

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

答案 1 :(得分:1)

从预期的结果来看,听起来你正在尝试解码一个小端32位整数。 binary.Uvarint函数对于作业来说是错误的,因为它解码了Protocol Buffers规范使用的可变长度整数编码。

相反,请尝试使用binary.LittleEndian.Uint32()

val := binary.LittleEndian.Uint32(slice)

答案 2 :(得分: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