猿问

Go Varint 返回一半的预期值

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


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


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


幕布斯7119047
浏览 133回答 2
2回答

暮色呼如

使用该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。这样做是因为,它在“我知道这个数字是有符号的”上下文中运行 - 这就是该函数存在的原因:0001001000000001--------00000000     = 0那时,零确实等于零——因此该方法返回x——即 9。让我们试试 1使用 1 作为输入:00000001右移:00000000AND原始数字 (1)与 1:0000000100000001--------     = 1此时,结果不等于零..所以结果反转:11111111这是-1(注意符号位现在是 1 .. 表示负数)的有符号表示。
随时随地看视频慕课网APP

相关分类

Go
我要回答