2016-01-10 60 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類型。