将[]字节转到Little / Big-Endian Signed Integer或Float?

时间:2016-01-10 02:00:04

标签: go

我能够将[]byte转换为无符号整数:

a := binary.LittleEndian.Uint16(sampleA)
b := binary.BigEndian.Uint32(sampleB)

这会利用Go包中的BigEndian和LittleEndian类型https://golang.org/src/encoding/binary/binary.go

这提供Uint16()但是没有等效的Int16()Float32()

为什么不考虑?那怎么办呢?

2 个答案:

答案 0 :(得分:5)

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

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

例如,如果您已经有uint16值,要将其用作签名值,您只需要conversion类型,因为uint16和{{的内存布局1}}是相同的(从int16转换为uint16不会改变内存表示只是类型):

int16

类似地:

a := binary.LittleEndian.Uint16(sampleA)
// If you need int16:
a2 := int16(a)

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

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

例如:

a := binary.LittleEndian.Uint64(sampleA)
// If you need int64:
a2 := int64(a)

如果您要从a := binary.LittleEndian.Uint64(sampleA) // If you need a float64: a2 := math.Float64frombits(a) 包中查看这些函数的实现,您可以看到内存值/布局没有被操纵,只是"查看"作为一种不同的类型,使用unsafe包。例如:

math

正如Paul所提到的,func Float32frombits(b uint32) float32 { return *(*float32)(unsafe.Pointer(&b)) } 软件包提供了Read()Write()功能来完成这些转换,因此您不需要这样做。

展示使用相同的" pi"示例(来自binary的文档):

binary.Read()

输出(在Go Playground上尝试):

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)

答案 1 :(得分:2)

ByteOrder类型提供用于解码二进制值的低级API。要读取float64或其他类型,可以使用binary.Readexample上有一个godoc page for the binary package,我在此处复制了这些内容:

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中的类型。