从代表二进制的字符串转换为浮点数
Posted
技术标签:
【中文标题】从代表二进制的字符串转换为浮点数【英文标题】:Go convert to float from string which represent binary 【发布时间】:2021-10-12 22:40:26 【问题描述】:转到 gRPC 元数据,获取并转换值。
在我的日志中,我看到元数据正在被翻译成另一种类型(我认为是字节数组)
"latitude-bin":"\ufffd\u0019\u0014\ufffd\ufffdϑL","longitude-bin":"@Z\ufffd\ufffd\ufffd\u000e\ufffdD"
如果我没记错的话,这两个值都应该是 Double。
我想在 Golang 中将这些值转换为 Double
或 float64
,但我对我的方法有点不确定,因为我不知道 latitude-bin
或 longitude-bin
的类型,我也不知道重现这些值(从我的客户的日志中获取)
这是我的方法
// GetLangitute get latitude from metadata `latitude-bin` and return nil when fails
func GetLangitute(ctx context.Context) *float64
metadataList := getMetaDataListByKey(ctx, latitudeBin)
if metadataList != nil
s := metadataList[metadataIndex]
b := []byte(s)
// TODO:
// I'm still a bit unsure about this approach
data := math.Float64frombits(binary.BigEndian.Uint64(b))
return &data
return nil
func getMetaDataListByKey(ctx context.Context, key string) []string
md, ok := metadata.FromIncomingContext(ctx)
if !ok
return nil
metadataList := md.Get(key)
if isEmpty(metadataList)
return nil
return metadataList
func isEmpty(metadataList []string) bool
return len(metadataList) == 0
我尝试使用单元测试进行测试并且看起来不错,但我仍然不确定预期的结果,因为我无法重现它,这是我的单元测试
f := math.Float64frombits(uint64(6662343813755067509))
// ...
name: "Given key exist in metadata",
args: args
ctx: metadata.NewIncomingContext(
context.Background(),
metadata.Pairs("latitude-bin", `\ufffd\u0019\u0014\ufffd\ufffdϑL`),
),
,
want: &f,
// ...
t.Run(tt.name, func(t *testing.T)
got := GetLangitute(tt.args.ctx)
if tt.want != nil
if *got != *tt.want
t.Errorf("GetLangitute() = %v, want %v", got, tt.want)
else
assert.Nil(t, got)
)
【问题讨论】:
【参考方案1】:不幸的是,您的输入 JSON 似乎已经“搞砸”了。 JSON 中的纬度和经度值是 8 字节值,但它们不代表原始值。原始值丢失。
Go 将字符串存储为 UTF-8 编码的字节序列。在将其他类型转换为字符串(例如int
)时,遇到无效值时,转换将导致Unicode替换字符0xFFFD
。
您的输入包含多个这些符文:\ufffd
。这意味着生成输入 JSON 的编码算法有问题并导致信息丢失。您不太可能重现原始的纬度和经度值。
您必须修复源代码的编码部分。
注意:如果您的输入有效/正确,您可以像这样简单地将 string
值转换为 []byte
:
b := []byte(s)
无论s
是否包含有效的UTF-8 序列,上述转换都会产生s
的字节。
【讨论】:
你说得对,好像有东西截取了值。我与 FE 团队交谈,他们向我们发送了这样的值41cdcd6500000000
他们告诉我们如何使用 Kotlin 生成这些值,我注意到这些值与服务器日志相比有所不同
这里是如何从客户端(Kotlin)pl.kotl.in/kte_JvwIA生成值以上是关于从代表二进制的字符串转换为浮点数的主要内容,如果未能解决你的问题,请参考以下文章
如何在python中将23位浮点数从字符串转换为浮点数并返回?