Heim > Backend-Entwicklung > Golang > Wie konvertiere ich Bytes in ein Float32-Array in Go?

Wie konvertiere ich Bytes in ein Float32-Array in Go?

王林
Freigeben: 2024-02-06 08:33:08
nach vorne
999 Leute haben es durchsucht

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

Frageninhalt

Ich schreibe ein Array von Float32-Zahlen im Byte-Format aus einem Python-Skript in einen Elasticache-Redis-Cluster und lese dann die Bytes (als String) aus Elasticache in einem Go-Skript. Wie konvertiere ich Bytes als String im Go-Skript zurück in das ursprüngliche Float32-Array?

Python-Beispiel:

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})
Nach dem Login kopieren

Dies ist ein Beispiel, das ich in Go (Spielplatz) ausprobiert habe

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]
}
Nach dem Login kopieren


Richtige Antwort


Der Beispielcode, den Sie verwendet haben, ist „Hex konvertieren, dargestellt als Zeichenfolge“; Sie haben die Rohbytes (ich glaube, basierend auf aHex:CDCC8C3FCDCC0C4033335340), sodass eine direkte Konvertierung einfacher ist (obwohl Sie nur Bytes in a konvertieren könnten). Hex-String erstellen und dann die Konvertierung durchführen, es fügt nur unnötige Arbeit/Komplexität hinzu).

Aus dieser Antwort erhalten wir (Spielplatz):

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
}
Nach dem Login kopieren

Aktualisierte Referenzkommentare:

Ich bin immer noch etwas verwirrt darüber, was Sie erhalten haben, also probieren wir beide Möglichkeiten aus.

Wenn die Redis-Abfrage Rohdaten (Bytes) als Go-String (d. h. "xcdxccx8c?xcdxccx0c@33S@") zurückgibt, können Sie Konvertieren "xcdxccx8c?xcdxccx0c@33S@"),那么你可以 转换为 []byte in []byte (Playground)

func main() {
    var aBytesStr string = "\xcd\xcc\x8c?\xcd\xcc\x0c@33S@"
    fmt.Println(GetFloatArray([]byte(aBytesStr)))
}
Nach dem Login kopieren

Wenn Redis eine Zeichenfolge zurückgibt, die eine ASCII-Darstellung (/UTF-8) enthält (d. h. CDCC = []byte{0x41, 0x44, 0x43, 0x43}), ist es wahrscheinlich am einfachsten, diese mit encoding/hex (Playground)

zu dekodieren
func main() {
    aHex := "CDCC8C3FCDCC0C4033335340"
    b, err := hex.DecodeString(aHex)
    if err != nil {
        panic(err)
    }
    fmt.Println(GetFloatArray(b))
}
Nach dem Login kopieren

Beachten Sie, dass Ihr ursprünglicher Ansatz funktionieren könnte. Wie jedoch in den Kommentaren oben erwähnt, müssen Sie sich mit Endianness befassen, damit das Folgende funktioniert (Playground – Sie können effizienter sein, ich bin hier, um Klarheit zu schaffen) :

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)
Nach dem Login kopieren

Dabei werden jedoch Annahmen über die CPU getroffen, auf der der Code ausgeführt wird, was bedeutet, dass die vorherige Antwort vorzuziehen ist.

Das obige ist der detaillierte Inhalt vonWie konvertiere ich Bytes in ein Float32-Array in Go?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage