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

Bagaimana untuk menukar bait kepada tatasusunan float32 dalam Go?

王林
Lepaskan: 2024-02-06 08:33:08
ke hadapan
915 orang telah melayarinya

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})
Salin selepas log masuk

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]
}
Salin selepas log masuk


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
}
Salin selepas log masuk

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)))
}
Salin selepas log masuk

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))
}
Salin selepas log masuk

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)
Salin selepas log masuk

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!

Label berkaitan:
sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan