从代表二进制的字符串转换为浮点数

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 中将这些值转换为 Doublefloat64,但我对我的方法有点不确定,因为我不知道 latitude-binlongitude-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位浮点数从字符串转换为浮点数并返回?

如果以十进制形式收到的值是一个空字符串,我该如何将其转换为浮点数?

opencv c++:将图像矩阵从无符号字符转换为浮点数

无法在python中将字符串转换为浮点数

朴素贝叶斯高斯抛出 ValueError:无法将字符串转换为浮点数:'M'