【问题标题】:How to precisely calculate distances in Java?如何在 Java 中精确计算距离?
【发布时间】:2020-11-26 13:55:26
【问题描述】:

我正在使用this answer 的实现来为我的 GPS 跟踪软件计算两点之间的距离。

但是,我在许多 StackOverFlow 上读到使用 double 是不好的 because of the inaccurate float representation of values。因此,我在问:

  • 使用BigDecimal 计算距离会更准确吗?
  • 将结果从 BigDecimal 转换回 double 会产生额外的不准确性吗? (存储或检索值)

【问题讨论】:

  • 您的结果必须有多精确?纳米精度的地理定位还是米精度就足够了?
  • 距离的计算无论如何都是不准确的,因为您是在近似地球形状的基础上计算距离。你确定双打的不准确性是相关的吗?
  • double 基本上适用于您测量的大多数事物(简而言之,因为测量结果可能已经比 double 所能承受的精度低),但是对于您可以精确计数的任何东西都不理想(简而言之,因为double 引入的小错误在您以精确单位计数时是无法容忍的)。换句话说:从已经不精确的 GPS 结果中计算距离,double 绰绰有余。
  • 地球的周长约为 40,000 公里,因此您可能不需要存储大于 4000 万的数字。该数字的最小精度单位是Math.ulp(40_000_000.0) == 7.45e-9 - 所以,7nm。
  • 噗,英里,公里,难怪哥伦布以为他到了中国!

标签: java math floating-point gps latitude-longitude


【解决方案1】:

是的,理论上在BigDecimal 中进行任何计算都可以提高精度,但这非常实际上不太可能有帮助,原因如下:

  • 正如您发现的那样,有一些非天真的算法可以仅使用 double 来计算距离,而不会出现过多的数值错误。
  • 此用例的double 值的精度比您可能开始使用的任何位置信息的精度和准确度高出许多数量级。这意味着测量误差肯定会大于使用double引起的数值误差。

如果你还是在BigDecimal 中进行了计算,然后将结果转换为double,那么你当然会失去精度,因为BigDecimal 可以有效地任意精确,但double 可以' t.

但同样:精度损失与您描述的用例无关。

【讨论】:

  • 确实,直到逗号后的第十位,我得到的结果都是一样的。感谢您的回答!
【解决方案2】:

不,使用BigDecimal 代替double 不会显着提高此算法的准确性。

错误的主要来源是建模错误:您使用的公式假设地球是一个完美的球体。这意味着结果可能有多达 0.5% 的错误。使用 double 得到的舍入误差约为 0.000000000001%。

要获得更准确的结果,您可以使用例如Vincenty's formulae,它假设地球是一个椭球体,但它比大圆距离更难实现。要获得更准确的结果,您应该考虑当地的地形,这更难。

进一步阅读:https://en.m.wikipedia.org/wiki/Geographical_distance

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 2020-07-08
    • 1970-01-01
    • 2012-04-30
    相关资源
    最近更新 更多