我正在将一个 float32 数字数组以字节格式从 Python 脚本写入 Elasticache Redis 集群,然后在 Go 脚本中从 Elasticache 读取字节。如何在 Go 脚本中将字节转换回原始 float32 数组?
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})
这是我在 Go 中尝试过的示例,遵循 如何将十六进制转换为浮点数
import (
"fmt"
"math"
"strconv"
"<private utils library>/redis"
)
func GetFloatArray() []float32 {
aBytes, err := redis.<private function to get bytes from Elasticache for key1>
if err != nil {
return
}
aHex := fmt.Sprintf("%X", aBytes)
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))
}
}
当我在 Go 脚本中输出 aBytes、aHex 和 aArr 时,我得到:
aBytes: \ufffď?\ufffd\ufffd\u000c@33S@ #does not match original bytes \xcd\xcc\x8c?\xcd\xcc\x0c@33S@
aHex: CDCC8C3FCDCC0C4033335340
aArr: [-4.289679e+08 -4.2791936e+08 4.17524e-08] #does not match original array [1.1 2.2 3.3]
您使用的示例代码是“转换十六进制,表示为字符串”;您拥有原始字节,因此直接转换更简单(虽然您可以将字节转换为十六进制字符串,然后再转换,这样做只会增加不必要的工作/复杂性)。
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
}