Maison > développement back-end > Golang > Comment convertir des octets en tableau float32 dans Go ?

Comment convertir des octets en tableau float32 dans Go ?

王林
Libérer: 2024-02-06 08:33:08
avant
948 Les gens l'ont consulté

Go 中如何将字节转换为 float32 数组?

Contenu de la question

J'écris un tableau de nombres float32 au format octets sur un cluster Elasticache Redis à partir d'un script Python, puis je lis les octets (sous forme de chaîne) d'Elasticache dans un script Go. Comment reconvertir les octets sous forme de chaîne en tableau float32 d'origine dans le script Go ?

Exemple Python :

import numpy as np
import redis
a = np.array([1.1, 2.2, 3.3], dtype=np.float32)
a_bytes = a.tobytes(order="C") #I have also tried order="F" with no luck
print(a_bytes) #Output: b'\xcd\xcc\x8c?\xcd\xcc\x0c@33S@'
redis_client = redis.cluster.RedisCluster(host=<elasticache config endpoint>, port=6379)
redis_client.mset_nonatomic({"key1": a_bytes})
Copier après la connexion

C'est un exemple que j'ai essayé dans Go (aire de jeux)

package main

import (
    "fmt"
    "math"
    "strconv"
)

func main() {
    // aBytesStr is an example value retrieved from Elasticache
    // aBytesStr is type string, not raw bytes
    var aBytesStr string = "\xcd\xcc\x8c?\xcd\xcc\x0c@33S@"
    aHex := fmt.Sprintf("%X", aBytesStr)
    fmt.Println(aHex) // Output: CDCC8C3FCDCC0C4033335340
    var aArr [3]float32
    for i := 0; i < 3; i++ {
        aHex1 := aHex[i*8 : i*8+8]
        aParsed, err := strconv.ParseUint(aHex1, 16, 32)
        if err != nil {
            return
        }
        aArr[i] = math.Float32frombits(uint32(aParsed))
    }
    fmt.Println(aArr)
    // Expected output: [1.1 2.2 3.3]
    // Actual output [-4.289679e+08 -4.2791936e+08 4.17524e-08]
}
Copier après la connexion


Réponse correcte


L'exemple de code que vous avez utilisé est "convertir l'hexadécimal, représenté sous forme de chaîne" ; vous avez les octets bruts (je pense basé sur aHex:CDCC8C3FCDCC0C4033335340), donc une conversion directe est plus simple (bien que vous puissiez simplement octets en un chaîne hexadécimale puis effectuez la conversion, cela ajoute simplement du travail/de la complexité inutile).

De cette réponse nous obtenons (Playground) :

func GetFloatArray(aBytes []byte) []float32 {
    aArr := make([]float32, 3)
    for i := 0; i < 3; i++ {
        aArr[i] = BytesFloat32(aBytes[i*4:])
    }
    return aArr
}

func BytesFloat32(bytes []byte) float32 {
    bits := binary.LittleEndian.Uint32(bytes)
    float := math.Float32frombits(bits)
    return float
}
Copier après la connexion

Commentaires de référence mis à jour :

Je suis encore un peu confus quant à ce que vous avez reçu, alors essayons les deux possibilités.

Si la requête Redis renvoie des données brutes (octets) sous forme de chaîne go (c'est-à-dire "xcdxccx8c?xcdxccx0c@33S@"), alors vous pouvez Convertir "xcdxccx8c?xcdxccx0c@33S@"),那么你可以 转换为 []byte en []byte (Playground)

func main() {
    var aBytesStr string = "\xcd\xcc\x8c?\xcd\xcc\x0c@33S@"
    fmt.Println(GetFloatArray([]byte(aBytesStr)))
}
Copier après la connexion

Si Redis renvoie une chaîne contenant une représentation ASCII (/UTF-8) (c'est-à-dire CDCC = []byte{0x41, 0x44, 0x43, 0x43}), le moyen le plus simple est probablement de la décoder en utilisant encoding/hex (Playground)

func main() {
    aHex := "CDCC8C3FCDCC0C4033335340"
    b, err := hex.DecodeString(aHex)
    if err != nil {
        panic(err)
    }
    fmt.Println(GetFloatArray(b))
}
Copier après la connexion

Notez que votre approche originale peut fonctionner, cependant, comme indiqué dans les commentaires ci-dessus, vous devez gérer Endianness donc ce qui suit fonctionnera (playground - vous pouvez être plus efficace, je suis ici pour plus de clarté) :

byte1 := aHex[i*8 : i*8+2]
byte2 := aHex[i*8+2 : i*8+4]
byte3 := aHex[i*8+4 : i*8+6]
byte4 := aHex[i*8+6 : i*8+8]
aParsed, err := strconv.ParseUint(byte4+byte3+byte2+byte1, 16, 32)
Copier après la connexion

Cependant, cela fait des hypothèses sur le processeur qui exécute le code, ce qui signifie que la réponse précédente est préférable.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal