Heim > Artikel > Backend-Entwicklung > Wie konvertiere ich Bytes in ein Float32-Array in Go?
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] }
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)
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!