Go float64不适用于纬度和经度

时间:2015-06-11 15:06:53

标签: go numbers precision

我试图用json对象精确地解析纬度和经度,然后我为这个作业选择了float64。但是,float64以某种方式使数字四舍五入,我不知道该怎么做以避免舍入。

我已经创建了一个快速代码段,因此您可以执行此问题: http://play.golang.org/p/9g6Imn-7GK

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)
    }
}

1 个答案:

答案 0 :(得分:12)

实用的解决方案:

什么都不做。

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

小数点后八位(数字中有15位)表示距离约为1.1mm。我怀疑你的测量结果是否准确到达这个程度,而且更多的东西变得非常愚蠢。小数点后5位约为1.1m,属于理智范围,不受浮点误差的影响。

wikipedia page on Decimal Degrees可能有助于确定哪些值对您的项目合理。

一些注意事项:

有两个潜在的问题在起作用:

  1. 浮点

    一些可能揭示浮点问题的读物:

    如果您阅读这些内容,并了解浮点的工作原理 练习,你可以开悟,并了解发生了什么 以及如何解决它。

  2. 衡量精度

    在我看来,这是一个更大的问题。您发布的一个号码是13.519004709972312,显示为13.519004709972313。价值是否已经改变了#34;或不(参见:1),我试图计算每个软件计算器计算返回0这些值之间的差异,这是指示性的。

    手动计算显示值中0.000000000000001的差异。也就是说,在尾随之前有14个零,或1^-15

    wikipedia page on Latitude说:

      

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

    从此向后工作,纬度中第15个小数位所代表的位置差异对应的距离约为0.00000011mm 或0.11纳米。

    来自The Physics Factbook' Diameter of an Atom页面:

      

    原子比最厚的人发小一百万倍。原子的直径范围为约0.1至0.5纳米

    因此,您的测量将是"关闭"最多为单个原子直径的1/10。

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