J'essaie de convertir un []uint8
tableau d'octets dans un float64
dans GoLang. Je ne trouve pas de solution à ce problème en ligne. J'ai vu des suggestions de conversion en chaîne d'abord, puis en float64
mais cela ne semble pas fonctionner, il perd sa valeur et je me retrouve avec des zéros.
Exemple:
metric.Value, _ = strconv.ParseFloat(string(column.Value), 64)
Et ça ne marche pas ...
Par exemple,
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)
}
Production:
[24 45 68 84 251 33 9 64]
3.141592653589793
Comme le lisent les commentaires, tout dépend du type de données que vous avez dans votre []uint8
tranche.
S'il s'agit d'octets représentant une valeur à virgule flottante IEEE 754 dans l'ordre Little Endian, utilisez la réponse de Kluyg ou de peterSo (meilleure performance sans utilisation de la réflexion).
S'il s'agit d'une représentation textuelle en encodage Latin-1/UTF-8, alors vous devriez pouvoir faire ce que vous venez de faire:
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)
}
Résultat:
1,23
Aire de jeux: http://play.golang.org/p/-7iKRDG_ZM
Je pense que cet exemple de la documentation Go est ce que vous recherchez: 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)
Impressions 3.141592653589793
J'espère que ce hack vous aidera. Le but est de convertir le long flux de nombres binaires en flottant.
Par exemple: 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
}