英文:
Convert byte slice "[]uint8" to float64 in GoLang
问题
我正在尝试将一个[]uint8
字节切片转换为Go语言中的float64
类型。我在网上找不到解决这个问题的方法。我看到有建议先转换为字符串,然后再转换为float64
,但这似乎不起作用,它会丢失其值,最终得到的是零。
示例:
metric.Value, _ = strconv.ParseFloat(string(column.Value), 64)
但这并不起作用...
英文:
I'm trying to convert a []uint8
byte slice into a float64
in GoLang. I can't find a solution for this issue online. I've seen suggestions of converting to a string first and then to a float64
but this doesn't seem to work, it loses it's value and I end up with zeroes.
Example:
metric.Value, _ = strconv.ParseFloat(string(column.Value), 64)
And it doesn't work...
答案1
得分: 67
例如,
package main
import (
"encoding/binary"
"fmt"
"math"
)
func Float64frombytes(bytes []byte) float64 {
bits := binary.LittleEndian.Uint64(bytes)
float := math.Float64frombits(bits)
return float
}
func Float64bytes(float float64) []byte {
bits := math.Float64bits(float)
bytes := make([]byte, 8)
binary.LittleEndian.PutUint64(bytes, bits)
return bytes
}
func main() {
bytes := Float64bytes(math.Pi)
fmt.Println(bytes)
float := Float64frombytes(bytes)
fmt.Println(float)
}
输出:
[24 45 68 84 251 33 9 64]
3.141592653589793
英文:
For example,
package main
import (
"encoding/binary"
"fmt"
"math"
)
func Float64frombytes(bytes []byte) float64 {
bits := binary.LittleEndian.Uint64(bytes)
float := math.Float64frombits(bits)
return float
}
func Float64bytes(float float64) []byte {
bits := math.Float64bits(float)
bytes := make([]byte, 8)
binary.LittleEndian.PutUint64(bytes, bits)
return bytes
}
func main() {
bytes := Float64bytes(math.Pi)
fmt.Println(bytes)
float := Float64frombytes(bytes)
fmt.Println(float)
}
Output:
[24 45 68 84 251 33 9 64]
3.141592653589793
答案2
得分: 6
我认为你正在寻找的是Go文档中的这个示例:
http://golang.org/pkg/encoding/binary/#example_Read
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)
打印结果为3.141592653589793。
英文:
I think this example from Go documentation is what you are looking for:
http://golang.org/pkg/encoding/binary/#example_Read
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)
Prints 3.141592653589793
答案3
得分: 6
根据评论所说,一切取决于你的[]uint8
切片中包含的是什么类型的数据。
如果它是表示IEEE 754浮点数值的字节,采用Kluyg或peterSo的答案(后者性能更好,不使用反射)。
如果它是Latin-1/UTF-8编码的文本表示,则你应该能够像你刚才做的那样操作:
package main
import (
"fmt"
"strconv"
)
func main() {
var f float64
text := []uint8("1.23") // 以Latin-1文本表示的十进制值
f, err := strconv.ParseFloat(string(text), 64)
if err != nil {
panic(err)
}
fmt.Println(f)
}
结果:
1.23
Playground: http://play.golang.org/p/-7iKRDG_ZM
英文:
As the comments read, it all depends on what kind of data you have in your []uint8
slice.
If it is bytes representing an IEEE 754 floating-point value in Little Endian order, then use Kluyg's or peterSo's (better performance without use of reflection) answer.
If it is a textual representation in Latin-1/UTF-8 encoding, then you should be able to do what you just did:
package main
import (
"fmt"
"strconv"
)
func main() {
var f float64
text := []uint8("1.23") // A decimal value represented as Latin-1 text
f, err := strconv.ParseFloat(string(text), 64)
if err != nil {
panic(err)
}
fmt.Println(f)
}
Result:
>1.23
Playground: http://play.golang.org/p/-7iKRDG_ZM
答案4
得分: 2
我希望这个技巧能有所帮助。它的目的是将一长串二进制数转换为浮点数。
例如:
0110111100010010100000111100000011001010001000010000100111000000 -> -3.1415
func binFloat(bin string) float64 {
var s1 []byte
var result float64
if len(bin) % 8 == 0 {
for i := 0; i < len(bin) / 8; i++ {
// 将字符串分割成长度为8的片段
// 将字符串转换为整数,再转换为字节
num, _ := strconv.ParseInt(bin[8*i: 8*(i + 1)], 2, 64)
// 将字节存入切片s1
s1 = append(s1, byte(num))
}
}
// 将字节切片转换为float64类型
// 下面的算法来自于golang二进制示例
buf := bytes.NewReader(s1)
// 你也可以将binary.LittleEndian改为binary.BigEndian
// 有关字节序的详细信息,请搜索字节序
err := binary.Read(buf, binary.LittleEndian, &result)
if err != nil {
panic(err)
fmt.Println("二进制长度不是8的倍数")
}
return result
}
英文:
I hope this hack helps. The purpose of it is to convert the long stream of binary numbers to float.
For example:
0110111100010010100000111100000011001010001000010000100111000000 -> -3.1415
func binFloat(bin string) float64 {
var s1 []byte
var result float64
if len(bin) % 8 == 0 {
for i := 0; i < len(bin) / 8; i++ {
//Chop the strings into a segment with a length of 8.
//Convert the string to Integer and to byte
num, _ := strconv.ParseInt(bin[8*i: 8*(i + 1)], 2, 64)
//Store the byte into a slice s1
s1 = append(s1, byte(num))
}
}
//convert the byte slice to a float64.
//The algorithm below are copied from golang binary examples.
buf := bytes.NewReader(s1)
//You can also change binary.LittleEndian to binary.BigEndian
//For the details of Endianness, please google Endianness
err := binary.Read(buf, binary.LittleEndian, &result)
if err != nil {
panic(err)
fmt.Println("Length of the binary is not in the length of 8")
}
return result
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论