gpt4 book ai didi

Go Varint 返回预期值的一半

转载 作者:数据小太阳 更新时间:2023-10-29 03:35:52 24 4
gpt4 key购买 nike

为什么这段代码的输出是:

package main

import (
"fmt"
"encoding/binary"
)

func main() {
var myByte byte = 18
array := []byte{myByte}
val, n := binary.Varint(array)
fmt.Printf("value: %d, num bytes: %d\n", val, n)
}

value: 9, num bytes: 1 而不是 value: 18, num bytes: 1

这可能与二进制补码有关,但我不知道如何。

最佳答案

TLDR:使用 Uvarint 方法正确解码 unsigned 字节 .. 这就是 byte默认情况下。

字节是无符号存储的(默认情况下字节是无符号的 - 它是 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

在这一点上,结果不等于 0.. 所以结果是反转的:

11111111

这是 -1 的符号表示(注意符号位现在是 1 .. 表示负数)。

关于Go Varint 返回预期值的一半,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28036560/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com