Golang中将字节数组转换为有符号整数的方法

Golang中将字节数组转换为有符号整数的方法 你好, 我有以下示例代码。它的功能是将十六进制字符串转换为字节数组,然后我想将其转换为对应的整数值。问题在于它没有给出整数的有符号版本。在这个例子中,值应该是 -12269766,但我一直得到 1717974068。如何获取有符号版本?

package main

import (
	"encoding/binary"
	"fmt"
)

func main() {
	
	str := "ff44c73a"
	data := []byte(str)
	fmt.Println(data)

	a := binary.BigEndian.Uint32(data)
	// If you need int64:
	a2 := int32(a)
	fmt.Println(a2)

}

更多关于Golang中将字节数组转换为有符号整数的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

好的,Skillian, 现在我完全明白了。我正在慢慢掌握 Go 语言。

更多关于Golang中将字节数组转换为有符号整数的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好 Skillian,

感谢你,我会尝试你的解决方案。只是对 a := binary.BigEndian.Uint32(data) 这一行感到好奇,它的作用是将数据转换为无符号整数,对吗?那么 a2 := int32(a) 这一行是如何将其转换为有符号整数的呢?

在Go语言中,有符号和无符号整数类型之间的转换本质上是复制源值的比特位,并将其“重新标记”为目标类型。也就是说,uint32(4282697530)int32(-12269766) 在内存(或CPU寄存器)中的实际比特位是相同的。就像 uint32(0xffffffff)int32(-1) 是相同的一样。这是因为Go语言规范要求有符号整数运算使用二进制补码运算

字符串 "ff44c73a" 是一个由 8 个 UTF-8 编码字符组成的序列,其十六进制表示形式为:0x66 0x66 0x34 0x34 0x63 0x37 0x33 0x61。如果你希望这些字符被解释为十六进制,那么必须使用 \x 进行转义,例如:"\xff\x44\xc7\x3a"。当使用 binary.BigEndian 解码并转换为 int32 时,该字符串会产生值 -12269766:Go Playground - The Go Programming Language

func main() {
    fmt.Println("hello world")
}

要将字节数组正确解析为有符号整数,你需要使用 binary.BigEndian.Uint32() 获取无符号值后转换为 int32,但你的输入 data 是字符串 "ff44c73a" 的 ASCII 字节表示,而不是十六进制字节值。你需要先将十六进制字符串解码为字节数组。以下是修正后的代码:

package main

import (
	"encoding/binary"
	"encoding/hex"
	"fmt"
)

func main() {
	str := "ff44c73a"
	
	// 将十六进制字符串解码为字节数组
	data, err := hex.DecodeString(str)
	if err != nil {
		panic(err)
	}
	fmt.Printf("字节数组: %v\n", data)
	
	// 使用 BigEndian 解析为无符号 32 位整数
	u := binary.BigEndian.Uint32(data)
	fmt.Printf("无符号值: %d\n", u)
	
	// 转换为有符号 32 位整数
	i := int32(u)
	fmt.Printf("有符号值: %d\n", i)
	
	// 或者直接使用 binary.BigEndian.PutUint32 和类型转换
	// 但这里已经通过 Uint32 获取了值
}

输出:

字节数组: [255 68 199 58]
无符号值: 4282697530
有符号值: -12269766

关键点:

  1. 使用 hex.DecodeString() 将十六进制字符串转换为字节数组。
  2. binary.BigEndian.Uint32() 读取字节数组为无符号 32 位整数。
  3. uint32 转换为 int32 时,Go 会保留位模式,因此高位为 1 时会得到负值。

如果你的字节序是小端,可以使用 binary.LittleEndian.Uint32()

package main

import (
	"encoding/binary"
	"encoding/hex"
	"fmt"
)

func main() {
	str := "ff44c73a"
	data, _ := hex.DecodeString(str)
	
	// 小端字节序解析
	u := binary.LittleEndian.Uint32(data)
	i := int32(u)
	fmt.Printf("小端有符号值: %d\n", i)
}

对于 int64,确保字节数组长度为 8 字节:

package main

import (
	"encoding/binary"
	"encoding/hex"
	"fmt"
)

func main() {
	str := "ffffffff44c73a00"
	data, _ := hex.DecodeString(str)
	
	u := binary.BigEndian.Uint64(data)
	i := int64(u)
	fmt.Printf("64位有符号值: %d\n", i)
}
回到顶部