Go float64不适用于纬度和经度

Go float64不适用于纬度和经度,go,numbers,precision,Go,Numbers,Precision,我试图精确地解析json对象的纬度和经度,我选择了float64。然而,float64在某种程度上是四舍五入的,我不知道该怎么做才能避免四舍五入 我创建了一个快速代码段,以便您可以执行该问题: 一个切实可行的解决办法: 什么也不做 数字上的差异大约是单个小原子宽度的十分之一,你的测量不可能那么精确 小数点后第八位(数字中有15位)表示大约1.1毫米的距离。我怀疑你的测量是否精确到了这个程度,而且任何更多的测量都变得非常愚蠢。小数点后第5位约为1.1m,属于正常范围,不受浮点错误的影响 在确定哪

我试图精确地解析json对象的纬度和经度,我选择了float64。然而,float64在某种程度上是四舍五入的,我不知道该怎么做才能避免四舍五入

我创建了一个快速代码段,以便您可以执行该问题:

一个切实可行的解决办法: 什么也不做

数字上的差异大约是单个小原子宽度的十分之一,你的测量不可能那么精确

小数点后第八位(数字中有15位)表示大约1.1毫米的距离。我怀疑你的测量是否精确到了这个程度,而且任何更多的测量都变得非常愚蠢。小数点后第5位约为1.1m,属于正常范围,不受浮点错误的影响

在确定哪些值对于您的项目是合理的时,可能会有所帮助

一些考虑: 存在两个潜在问题:

  • 浮点

    一些阅读可能有助于了解浮点问题:

    如果您阅读了这些,并了解浮点在 练习,你可能会开悟,并理解正在发生的事情 以及如何解决这个问题

  • 测量精度

    在我看来,这是一个更大的问题。您发布的一个号码是
    13.519004709972312
    ,显示为
    13.519004709972313
    。无论值是否已“更改”(请参见:1),我尝试的每个软件计算器都会计算返回的这些值之间的差异
    0
    ,这是指示性的

    手工计算显示,数值之间的差异为
    0.00000000000001
    。也就是说,在后面的一个之前加上14个零,或者
    1^-15

    报告说:

    球体上1度纬度的子午线长度111.2km

    从这一点往回看,纬度中小数点后15位表示的位置差异对应于约0.00000011mm或0.11nm的距离

    从物理事实手册的页面:

    原子比人类最厚的头发小一百万倍。原子的直径在0.1到0.5纳米之间

    因此,您的测量值最多会“关闭”单个原子直径的1/10

    即使我所有的计算都偏离了一百万或十亿倍,距离仍然很小,以至于在实践中它们都无关紧要


  • 如果您想要比float64更高的精度,您可能应该使用
    math/big
    。我已经用完整的代码进行了编辑。Thanks@JimB,不知道如何做到这一点,你可以用你的建议修改游乐场的例子吗?如前所述,你可以(应该?)只使用float64和四舍五入。如果你有理由希望保留精确的字符串,也许会有一些用处。你还必须问自己,输入是如何生成的?如果在源位置使用了双精度数字,则最后的数字无论如何都不可信。通过使用
    float64
    ,您可以可靠地表示多达15位十进制数字,但您的输入有17位。感谢您提供非常完整的答案,我非常感谢@托马斯莫德内斯:也许你想接受这个人的答案
    package main
    
    import (
        "encoding/json"
        "fmt"
        "reflect"
    )
    
    type Position struct {
        Lat float64 `json:"lat"`
        Lon float64 `json:"lon"`
    }
    
    func main() {
        s := `{"lat":13.519004709972312,"lon": -13.519004709972312}`
        pos := Position{}
        json.Unmarshal([]byte(s), &pos)
    
        if !reflect.DeepEqual(s, &pos) {
            fmt.Printf("\nExpected %#v\nbut got  %#v", s, pos)
        }
    }