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

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

王林
王林nach vorne
2024-02-06 08:33:08883Durchsuche

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})

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]
}

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
}

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)))
}

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))
}

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)

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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen