Rumah >pembangunan bahagian belakang >Golang >Bagaimana untuk menukar bait kepada tatasusunan float32 dalam Go?

Bagaimana untuk menukar bait kepada tatasusunan float32 dalam Go?

王林
王林ke hadapan
2024-02-06 08:33:08949semak imbas

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

Kandungan soalan

Saya sedang menulis tatasusunan nombor float32 dalam format bait ke gugusan Elasticache Redis daripada skrip Python, dan kemudian membaca bait (sebagai rentetan) daripada Elasticache dalam skrip Go. Bagaimana untuk menukar bait-sebagai-rentetan kembali kepada tatasusunan float32 asal dalam skrip Go?

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

Ini adalah contoh yang saya cuba di Go (taman permainan)

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

Jawapan betul


Contoh kod yang anda gunakan ialah "tukar hex, diwakili sebagai rentetan"; anda mempunyai bait mentah (saya rasa berdasarkan aHex:CDCC8C3FCDCC0C4033335340) jadi penukaran langsung adalah lebih mudah (walaupun anda hanya boleh bait ke a rentetan hex dan kemudian lakukan penukaran, ia hanya menambah kerja/kerumitan yang tidak perlu).

Dari jawapan ini kami dapat (Taman Permainan):

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
}

Komen rujukan yang dikemas kini:

Saya masih keliru dengan apa yang anda terima, jadi mari kita cuba kedua-dua kemungkinan.

Jika pertanyaan redis mengembalikan data mentah (bait) sebagai rentetan pergi (iaitu "xcdxccx8c?xcdxccx0c@33S@"), maka anda boleh Tukar "xcdxccx8c?xcdxccx0c@33S@"),那么你可以 转换为 []byte kepada []bait (Taman Permainan)

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

Jika Redis mengembalikan rentetan yang mengandungi perwakilan ASCII (/UTF-8) (iaitu CDCC = []byte{0x41, 0x44, 0x43, 0x43}), cara paling mudah mungkin ialah menyahkod ini menggunakan pengekodan/hex (Taman Permainan)

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

Perhatikan bahawa pendekatan asal anda mungkin berkesan, namun, seperti yang dinyatakan dalam ulasan di atas, anda perlu menangani Endianness supaya perkara berikut akan berfungsi (taman permainan - anda boleh menjadi lebih cekap, saya di sini untuk kejelasan) :

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)

Walau bagaimanapun, ini membuat andaian tentang CPU yang menjalankan kod, yang bermaksud jawapan sebelumnya adalah lebih baik.

Atas ialah kandungan terperinci Bagaimana untuk menukar bait kepada tatasusunan float32 dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam