2016-01-10 59 views

回答

4

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

所有你需要的是组装一个16位,32位或64位的值,一旦完成,你可以根据需要解释结果。

例如,如果你已经有了一个uint16值,使用它作为一个符号的值,你需要的是一个类型conversion因为一个uint16int16内存布局是相同的(从转换到uint16int16不改变内存中的表示只是型):

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

类似地:

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

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

用于将无符号整数浮动类型中,可以使用具有相同的内存布局的math包的功能,即math.Float32frombits()math.Float64frombits(),并为反向(一个浮点值转换为无符号整数):math.Float32bits()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()的DOC)展示:

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 
2

ByteOrder类型为解码二进制值提供了一个低级API。要读取float64或其他类型,可以使用binary.Read。这里有一个examplegodoc 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类型。