c++ - 不同语言的浮点精度
问题描述
我目前正在计算坐标之间的距离,并且根据所使用的语言,得到的结果略有不同。
部分计算正在计算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 的位置增加了一个不小的距离。
不太确定这是如何重复的。此外,我更多地要求一个整体的答案,而不是特定于语言的答案。我没有计算机科学学位。
更新
我接受这个问题可能太宽泛了,我想我很好奇为什么我的背景不是 CS。我很欣赏评论中发布的博客链接。
更新 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 只要求基本运算(+-*/
)并sqrt
正确舍入,即误差必须不超过 0.5ULP。sin
, cos
, ...等超越函数exp
非常复杂,因此仅建议对它们进行适当的舍入。根据空间和时间要求,不同的实现可能使用不同的算法来计算这些函数的结果。因此,像您观察到的变化是完全正常的
没有标准要求对超越函数进行忠实四舍五入。IEEE-754 (2008)建议但不要求正确舍入这些函数。
也可以看看
推荐阅读
- php - 时间日期条件逻辑语句 MySQL
- java - Java 将“[”和“]”写入文本文件而不是“[”和“]”
- typescript - 对象的联合类型包含用 Promise 包装的布尔文字类型
- javascript - 比较使用 CSS 和状态管理隐藏 React 组件的性能
- python-3.x - 将 list() 函数应用于字典时会发生什么?
- mysql - 如何从 CURSOR 读取数据 - mysql 存储过程
- javascript - PhpStorm 无法 Ctrl+单击打开 JavaScript 工厂文件
- ios - 带有“上一个”和“下一个”键盘的工具栏
- javascript - 在 javascript 函数中传递字符串值
- c# - 这个 C# 语句的 VB.NET 版本中是否需要 unchecked 关键字?