去[]字节小/大端有符号整数或浮点? [英] Go []byte to Little/Big-Endian Signed Integer or Float?

查看:217
本文介绍了去[]字节小/大端有符号整数或浮点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以将 [] 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()



有什么想法为什么不呢?另外,如何做到这一点?

解决方案

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

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



例如,如果您已经有一个 uint16 值,可以使用它作为有符号值,您只需要输入转换,因为<$的内存布局c $ c> uint16 和 int16 是一样的(从 uint16 转换为 int16 不会改变内存表示的类型):

  a: = binary.LittleEndian.Uint16(sampleA)
//如果您需要int16:
a2:= int16(a)

同样:

  a:= binary.LittleEndian.Uint64(sampleA)
//如果你需要int64:
a2:= int64(a)

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

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



例如:

  a:= binary.LittleEndian.Uint64(sampleA)
//如果您需要float64:
a2:= math.Float64frombits(a)

如果您想从 math 包中查看这些函数的实现,您可以看到内存值/布局不被操纵,它只是被查看为不同的类型,通过使用 不安全 包。例如:

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

Paul提到,二元包提供了 Read() Write() 功能在引擎盖下进行这些转换,所以您不需要。



展示使用相同的pi示例(来自<$ c $的文档c> 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)

//使用LittleEndian.Uint64()和math.Float 64frombits()
A:= binary.LittleEndian.Uint64(B)
A2:= math.Float64frombits的(a)
fmt.Println(A2)

输出(在 Go Playground ):

  3.141592653589793 
3.141592653589793


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?

解决方案

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

这篇关于去[]字节小/大端有符号整数或浮点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆