我目前正在计算坐标之间的距离,并且根据所使用的语言获得的结果略有不同。
计算的一部分正在计算给定cosine
的radian
。我得到以下结果
// cos(0.8941658257446736)
// 0.6261694290123146 node
// 0.6261694290123146 rust
// 0.6261694290123148 go
// 0.6261694290123148 python
// 0.6261694290123148 swift
// 0.6261694290123146 c++
// 0.6261694290123146 java
// 0.6261694290123147 c
我想尝试并理解原因。如果您不顾16dp
,就舍入而言,c
是唯一的“正确”答案。我很惊讶python
的结果有所不同。
此小差异当前正在放大,并且在000多个位置中添加了不小的距离。
不太确定这是如何重复的。另外,我要求的是整体答案,而不是具体的语言。我没有计算机科学学位。
UPDATE我接受这可能是一个太宽泛的问题,我想我为什么对我的背景不是CS感到好奇。我感谢评论中发布的博客链接。
UPDATE 2
此问题源于将服务从nodejs
移植到go
。 Go
甚至更奇怪,因为距离的总和随多个值而变化,因此我现在无法运行测试。
给出一个坐标列表并计算距离并将它们加在一起,我得到不同的结果。我没有问问题,但是go
会产生不同的结果似乎很疯狂。
9605.795975874069
9605.795975874067
9605.79597587407
为了完整性,这里是我正在使用的距离计算:
func Distance(pointA Coordinate, pointB Coordinate) float64 {
const R = 6371000 // Earth radius meters
phi1 := pointA.Lat * math.Pi / 180
phi2 := pointB.Lat * math.Pi / 180
lambda1 := pointA.Lon * math.Pi / 180
lambda2 := pointB.Lon * math.Pi / 180
deltaPhi := phi2 - phi1
deltaLambda := lambda2 - lambda1
a := math.Sin(deltaPhi/2)*math.Sin(deltaPhi/2) + math.Cos(phi1)*math.Cos(phi2)*math.Sin(deltaLambda/2)*math.Sin(deltaLambda/2)
c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
d := R * c
return d
}
通常,浮点数的表示由标准IEEE 754定义,我的假设是该标准由所有(主要)编程语言实现。
精度和舍入为known issues,有时可能为lead to unexpected results。
根据编程语言或使用的数学库,可能对计算结果产生影响的方面:
您正在使用双精度浮点,并且可以根据所使用的语言来控制打印值的精度。对于C ++,您可以如下设置所需的精度
std::cout << std::setprecision(15) << value << '\n';
附带说明,C ++标准并未要求固有数学函数(例如余弦)具有精度。两种不同的STL实现可能会得出不同的结果。每个实现都可以自由选择满足其性能要求的精度。