为了账号安全,请及时绑定邮箱和手机立即绑定

将 []byte 转为 Little/Big-Endian 有符号整数或浮点数?

将 []byte 转为 Little/Big-Endian 有符号整数或浮点数?

Go
HUX布斯 2021-12-07 09:24:42
我能够转换[]byte为无符号整数:a := binary.LittleEndian.Uint16(sampleA)b := binary.BigEndian.Uint32(sampleB)这利用了 Go 包https://golang.org/src/encoding/binary/binary.go 中的 BigEndian 和 LittleEndian 类型 。Uint16()然而,这提供了没有等效的Int16()或Float32()。关于为什么不的任何想法?另外,这应该怎么做?
查看完整描述

2 回答

?
红糖糍粑

TA贡献1815条经验 获得超6个赞

将数字类型转换为一系列字节 ( []byte),反之亦然,这与字节序有关。您如何解释结果完全取决于您。


您所需要的只是组合一个 16 位、32 位或 64 位的值,一旦完成,您就可以根据需要解释结果。


例如,如果您已经有一个uint16值,要将其用作有符号值,您只需要进行类型转换,因为uint16and的内存布局int16是相同的(从uint16to转换int16不会仅更改类型的内存表示):


a := binary.LittleEndian.Uint16(sampleA)

// If you need int16:

a2 := int16(a)

相似地:


a := binary.LittleEndian.Uint64(sampleA)

// If you need int64:

a2 := int64(a)

uint -> float 转换的情况稍微复杂一些,因为使用简单的类型转换会尝试转换数值,而不仅仅是改变类型(因此会改变内存表示)。


要将无符号整数转换为浮点类型,您可以使用math包的函数,即math.Float32frombits()and math.Float64frombits(),以及具有相同内存布局的相反方向(将浮点值转换为无符号整数):math.Float32bits()and math.Float64bits()。


例如:


a := binary.LittleEndian.Uint64(sampleA)

// If you need a float64:

a2 := math.Float64frombits(a)

如果您从math包中查看这些函数的实现,您会发现内存值/布局没有被操纵,它只是通过使用unsafe包被“查看”为不同的类型。例如:


func Float32frombits(b uint32) float32 { return *(*float32)(unsafe.Pointer(&b)) }

正如保罗所说,binary包提供Read(),并Write()因此你不需要的功能做的引擎盖下这些转换。


展示使用相同的“pi”示例(来自 的文档binary.Read()):


b := []byte{0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40}


// USING binary.Read()

var pi float64

buf := bytes.NewReader(b)

err := binary.Read(buf, binary.LittleEndian, &pi)

if err != nil {

    fmt.Println("binary.Read failed:", err)

}

fmt.Println(pi)


// Using LittleEndian.Uint64() and math.Float64frombits()

a := binary.LittleEndian.Uint64(b)

a2 := math.Float64frombits(a)

fmt.Println(a2)

输出(在Go Playground上试试):


3.141592653589793

3.141592653589793


查看完整回答
反对 回复 2021-12-07
?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

该ByteOrder类型提供用于解码二进制值的低级 API。要读取 float64 或其他类型,您可以使用binary.Read. 二进制包的godoc 页面上有一个示例,我已将其复制到此处:


var pi float64

b := []byte{0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40}

buf := bytes.NewReader(b)

err := binary.Read(buf, binary.LittleEndian, &pi)

if err != nil {

    fmt.Println("binary.Read failed:", err)

}

fmt.Print(pi)

没有用于解码 float16 的函数,因为它不是 Go 中的类型。


查看完整回答
反对 回复 2021-12-07
  • 2 回答
  • 0 关注
  • 223 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信