首页 > 解决方案 > 不同语言的浮点精度

问题描述

我目前正在计算坐标之间的距离,并且根据所使用的语言,得到的结果略有不同。

部分计算正在计算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

这个问题源于将服务移植nodejsgo. 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
}

标签: c++floating-pointlanguage-agnosticprecisiontranscendental-equation

解决方案


IEEE-754 只要求基本运算(+-*/)并sqrt正确舍入,即误差必须不超过 0.5ULP。sin, cos, ...等超越函数exp非常复杂,因此仅建议对它们进行适当的舍入。根据空间和时间要求,不同的实现可能使用不同的算法来计算这些函数的结果。因此,像您观察到的变化是完全正常的

没有标准要求对超越函数进行忠实四舍五入。IEEE-754 (2008)建议但不要求正确舍入这些函数。

非常大数正弦的标准

也可以看看


推荐阅读