登录
首页 >  Golang >  Go问答

int64 的可变长度二进制补码

来源:Golang技术栈

时间:2023-03-09 08:43:47 190浏览 收藏

在IT行业这个发展更新速度很快的行业,只有不停止的学习,才不会被行业所淘汰。如果你是Golang学习者,那么本文《int64 的可变长度二进制补码》就很适合你!本篇内容主要包括int64 的可变长度二进制补码,希望对大家的知识积累有所帮助,助力实战开发!

问题内容

我正在尝试编写一个 Go 程序来解析 ans.1 BER 二进制补码整数编码。但是,整数可以具有 1、2、3 或 4 字节长度编码(取决于其大小)。

根据规范(http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf),最左边的位始终是补码。

什么是干净的方法来做到这一点?

func ParseInt(b []byte) (int64, error) {
    switch len(b) {
    case 1:
        // this works
        return int64(b[0]&0x7f) - int64(b[0]&0x80), nil
    case 2:
        // left most byte of b[0] is -32768
    case 3:
        // left most byte of b[0] is -8388608
    case 4:
        // left most byte of b[0] is -2147483648 (and so on for 5, 6, 7, 8)
    case 5:
    case 6:
    case 7:
    case 8:
    default:
        return 0, errors.New("value does not fit in a int64")
    }
}


ParseInt([]byte{0xfe})       // should return (-2, nil)
ParseInt([]byte{0xfe, 0xff}) // should return (-257, nil)
ParseInt([]byte{0x01, 0x00}) // should return (256, nil)

正确答案

如果您从末尾读取字节,则更容易理解:

  • 您不必移动最后一个字节
  • 将最后一个字节左移 8 位(一个字节中有 8 位)
  • 将倒数第二个字节左移 16
  • ...
  • 并且从第一个字节开始只使用 7 位,最左边的位是特殊的。

第一个字节的最左边位b[0]&080告诉您是否必须在结果中添加偏移量。可以选择添加的偏移量-1乘以您的输入将意味着通过设置这一位而设置所有其他位的数字0,即`-1

  • (1

例子。 如果输入...

  • 1 个字节:
    int64(b[0]&0x7f) - int64(b[0]&0x80)

  • 2个字节:
    int64(b[0]&0x7f)

  • 3 个字节:
    int64(b[0]&0x7f)

所有这些情况都可以用一个不错的循环来覆盖。

这是一个紧凑的实现(在Go Playground上试试):

func ParseInt(b []byte) (int64, error) {
    if len(b) > 8 {
        return 0, errors.New("value does not fit in a int64")
    }

    var n int64
    for i, v := range b {
        shift := uint((len(b) - i - 1) * 8)
        if i == 0 && v&0x80 != 0 {
            n -= 0x80 

文中关于golang的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《int64 的可变长度二进制补码》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:Golang技术栈 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>