1 回答
TA贡献1834条经验 获得超8个赞
引用文档encoding/binary:
varint 函数使用可变长度编码对单个整数值进行编码和解码;较小的值需要较少的字节。有关规范,请参阅https://developers.google.com/protocol-buffers/docs/encoding。
所以这binary.PutVarint()不是固定的,而是可变长度的编码。传递 时int64,大数需要 8 个字节以上,小数需要 8 个字节以下。由于您编码的数字是一个随机数,因此即使在其最高字节中也会有随机位。
看这个简单的例子:
buffer := make([]byte, 100)
for num := int64(1); num < 1<<60; num <<= 4 {
count := binary.PutVarint(buffer, num)
fmt.Printf("Num=%d, bytes=%d\n", num, count)
}
输出:
Num=1, bytes=1
Num=16, bytes=1
Num=256, bytes=2
Num=4096, bytes=2
Num=65536, bytes=3
Num=1048576, bytes=4
Num=16777216, bytes=4
Num=268435456, bytes=5
Num=4294967296, bytes=5
Num=68719476736, bytes=6
Num=1099511627776, bytes=6
Num=17592186044416, bytes=7
Num=281474976710656, bytes=8
Num=4503599627370496, bytes=8
Num=72057594037927936, bytes=9
可变长度编码的本质是小数字使用较少的字节,但这只能在大数字可能使用超过 8 个字节的情况下才能实现(即大小为int64)。
具体编码的详细信息在链接页面上。
一个非常简单的例子是:一个字节是 8 位。使用输出字节的 7 位作为“有用”位来编码数据/数字。如果最高位为 1,则意味着需要更多字节。如果最高位为 0,我们就完成了。你可以看到,小的数字可以使用1个输出字节编码(如n=10),而我们使用1个额外位,每7位有用的数据,因此,如果输入的号码使用所有64位,我们将结束与更多8 字节以上:需要 10 组来覆盖 64 位,因此我们将需要 10 字节(9 组仅 9*7=63 位)。
- 1 回答
- 0 关注
- 268 浏览
添加回答
举报