使用不同语言的浮点精度

问题描述 投票:5回答:2

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

计算的一部分正在计算给定cosineradian。我得到以下结果

// 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移植到goGo甚至更奇怪,因为距离的总和随多个值而变化,因此我现在无法运行测试。

给出一个坐标列表并计算距离并将它们加在一起,我得到不同的结果。我没有问问题,但是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
}
java c++ c go rust
2个回答
0
投票

通常,浮点数的表示由标准IEEE 754定义,我的假设是该标准由所有(主要)编程语言实现。

精度和舍入为known issues,有时可能为lead to unexpected results

根据编程语言或使用的数学库,可能对计算结果产生影响的方面:

  • 不同的计算方法(在您的情况下:余弦函数可能由numerical approximation使用不同的方法实现)
  • 计算期间的不同rounding modes
  • 最终输出的不同舍入策略

-1
投票

您正在使用双精度浮点,并且可以根据所使用的语言来控制打印值的精度。对于C ++,您可以如下设置所需的精度

std::cout << std::setprecision(15) << value << '\n';

附带说明,C ++标准并未要求固有数学函数(例如余弦)具有精度。两种不同的STL实现可能会得出不同的结果。每个实现都可以自由选择满足其性能要求的精度。

© www.soinside.com 2019 - 2024. All rights reserved.