2 回答
TA贡献1853条经验 获得超9个赞
使用该Uvarint方法正确解码无符号字节 .. 这是byte默认情况下的 a 。
字节以无符号形式存储(因为默认情况下字节是无符号的 -uint8在大多数语言中它是..的别名)。
当您解码数字时,您正在调用binary.Varint.. 解码一个带符号的数字。由于符号位,这会导致数字不正确。
使用binary.Uvarint.. 即解码一个无符号数,你会得到正确的结果:
val, n := binary.Uvarint(array) // val = 18, n = 1
扩展示例:
让我们看看你的数字 - 18。在二进制中,它是这样的:
00010010
该binary.Varint功能是以下:
func Varint(buf []byte) (int64, int) {
ux, n := Uvarint(buf) // ok to continue in presence of error
x := int64(ux >> 1)
if ux&1 != 0 {
x = ^x
}
return x, n
}
基本上,它首先会获取您提供的内容的无符号值:18。
然后它将所有字节移动 1。这导致:
00001001
那是 的二进制表示9。注意符号位仍然是 0 - 这意味着一个正数。然后,它通过将原始值 ( 18) 与进行按位与运算来检查是否反转结果1。这样做是因为,它在“我知道这个数字是有符号的”上下文中运行 - 这就是该函数存在的原因:
00010010
00000001
--------
00000000
= 0
那时,零确实等于零——因此该方法返回x——即 9。
让我们试试 1
使用 1 作为输入:
00000001
右移:
00000000
AND原始数字 (1)与 1:
00000001
00000001
--------
= 1
此时,结果不等于零..所以结果反转:
11111111
这是-1(注意符号位现在是 1 .. 表示负数)的有符号表示。
- 2 回答
- 0 关注
- 132 浏览
添加回答
举报