doushaiyu5065 2016-01-10 02:00
浏览 251
已采纳

将[] byte转换为Little / Big-Endian Signed Integer或Float?

I am able to convert []byte into unsigned integers:

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

This leverages the BigEndian and LittleEndian types within the Go package https://golang.org/src/encoding/binary/binary.go

This provides Uint16() however there are no equivalent Int16() or Float32()

Any thoughts on why not? Also, how ought this be done?

  • 写回答

2条回答 默认 最新

  • douxin20081125 2016-01-10 02:33
    关注

    Converting numeric types into a series of bytes ([]byte) and vice versa is about the endianness. How you interpret the result is entirely up to you.

    All you need is to assemble a 16-bit, 32-bit or 64-bit value, once it's done, you can interpret the result as you want.

    For example if you already have a uint16 value, to use it as a signed value, all you need is a type conversion because the memory layout of an uint16 and int16 is the same (converting from uint16 to int16 doesn't change the memory representation just the type):

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

    Similarly:

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

    The situation is a little more complicated with uint -> float conversion as using a simple type conversion would try to convert the numeric value and not just change the type (and thus would change the memory representation).

    For converting unsigned integers to float types, you can use functions of the math package, namely math.Float32frombits() and math.Float64frombits(), and for the reverse direction (converting a float value to an unsigned integer) having the same memory layout: math.Float32bits() and math.Float64bits().

    For example:

    a := binary.LittleEndian.Uint64(sampleA)
    // If you need a float64:
    a2 := math.Float64frombits(a)
    

    If you would look into the implementation of these functions from the math package, you can see that the memory value/layout is not manipulated, it is just "viewed" as a different type, by using the unsafe package. For example:

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

    As mentioned by Paul, the binary package provides Read() and Write() functions to do these conversions under the hood so you don't need to.

    Showcasing using the same "pi" example (from the doc of 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)
    

    Output (try it on the Go Playground):

    3.141592653589793
    3.141592653589793
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)