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

我能够转换[]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()。


关于为什么不的任何想法?另外,这应该怎么做?


HUX布斯
浏览 224回答 2
2回答

红糖糍粑

将数字类型转换为一系列字节 ( []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 float64buf := 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.1415926535897933.141592653589793

沧海一幻觉

该ByteOrder类型提供用于解码二进制值的低级 API。要读取 float64 或其他类型,您可以使用binary.Read. 二进制包的godoc 页面上有一个示例,我已将其复制到此处:var pi float64b := []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 中的类型。
打开App,查看更多内容
随时随地看视频慕课网APP