Go的float64类型不能用于表示纬度和经度。

huangapple go评论83阅读模式
英文:

Go float64 does not work for latitude and longitude

问题

我正在尝试从具有精度的 JSON 对象中解析纬度和经度,并选择了 float64 来完成这个任务。然而,float64 在某种程度上会四舍五入数字,我不确定该怎么做才能避免四舍五入。

我创建了一个快速的代码片段,你可以执行来解决这个问题:

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

请注意,我只翻译了代码部分,其他内容不做翻译。

英文:

I'm trying to parse latitude and longitude from a json object with precision, and I picked float64 for the job. However float64 is somehow rounding the number and I'm not sure what to do in order to avoid rounding.

I've created a quick snippet so you can execute the problem:
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

得分: 26

一个实际的解决方案:

什么都不做。

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

小数点后第八位(你的数字有15位小数)代表大约1.1毫米的距离。我怀疑你的测量精度达到这个程度,再往后的位数就变得非常荒谬了。第五位小数大约是1.1米,这是在合理范围内的,不会受到浮点数误差的影响。

维基百科关于十进制度数的页面可能对确定你的项目中哪些值是合理的有所帮助。

一些考虑因素:

有两个潜在的问题:

  1. 浮点数

    以下是一些可能对浮点数问题有所启发的阅读材料:

    如果你阅读了这些材料,并理解了浮点数在实践中的工作原理,你可能会有所启发,了解到正在发生什么以及如何解决这个问题。

  2. 测量精度

    在我看来,这是一个更大的问题。你发布的一个数字是13.519004709972312,但显示为13.519004709972313。无论这个值是否“改变”(参见:1),我尝试使用各种软件计算器计算这些值之间的差异,结果都是返回0,这是一个指示。

    手动计算发现这些值之间的差异为0.000000000000001。也就是说,一个尾随的1之前有14个零,或者说是1^-15

    维基百科关于纬度的页面上说:

    在球体上,1度纬度的子午线长度为111.2公里

    从这个结果反推回去,纬度的第15位小数所代表的位置差异相当于大约0.00000011毫米,或者说是0.11纳米

    根据《物理事实手册》的一个原子的直径页面:

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

    因此,你的测量结果最多只会偏离一个原子直径的十分之一。

    即使我所有的计算都偏差了一百万或十亿倍,这些距离仍然如此之小,以至于在实践中并不重要!

英文:

A practical solution:

Do nothing.

The difference in the numbers is about a tenth of the width of a single small atom, and your measurements can't possibly be that precise.

The eighth decimal place (you have 15 in your numbers) represents a distance of about 1.1mm. I doubt if your measurements are accurate to this degree, and anything more is getting really silly. The 5th decimal place is about 1.1m, which is in the realm of sanity, and not affected by floating point errors.

The wikipedia page on Decimal Degrees may be helpful in determining which values are reasonable for your project.

Some considerations:

There are two potential issues at play:

  1. Floating point:

    Some reading that might shed light on floating point issues:

    If you read these, and understand how floating point works in
    practice, you may be enlightened, and understand what's happening
    and how to work around it.

  2. Precision of measurement:

    This, in my opinion, is the bigger issue. One number you posted was 13.519004709972312, which was displayed as 13.519004709972313. Whether the value has "changed" or not (see: 1), every software calculator I tried to calculate the difference between these values returned 0, which is indicative.

    Doing the calculation by hand revealed a difference of 0.000000000000001 in the values. That is, a 14 zeroes before the trailing one, or 1^-15.

    The wikipedia page on Latitude says:

    > the meridian length of 1 degree of latitude on the sphere is 111.2 km.

    Working backward from this, the difference in locations represented by the 15th decimal place in a latitude corresponds to a distance of approximately 0.00000011mm, or 0.11nanometers.

    From the The Physics Factbook's Diameter of an Atom page:

    > An atom is a million times smaller than the thickest human hair. The diameter of an atom ranges from about 0.1 to 0.5 nanometers

    Therefore, your measurement would be "off" by at most 1/10 of the diameter of a single atom.

    Even if all my calculations were off by a million or billion times, the distances would still be so small that they would not matter in practice!

huangapple
  • 本文由 发表于 2015年6月11日 23:06:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/30784608.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定