简体   繁体   English

Java Math.toRadians(angle) vs 硬计算

[英]Java Math.toRadians(angle) vs hard-calculated

This question is related to another stackoverflow discussion distance between long&lat points这个问题与long&lat point之间的另一个stackoverflow讨论距离有关

Here is the code from the top voted answer:这是来自最高投票答案的代码:

/*
 * Calculate distance between two points in latitude and longitude taking
 * into account height difference. If you are not interested in height
 * difference pass 0.0. Uses Haversine method as its base.
 * 
 * lat1, lon1 Start point lat2, lon2 End point el1 Start altitude in meters
 * el2 End altitude in meters
 */
private double distance(double lat1, double lat2, double lon1, double lon2,
        double el1, double el2) {

    final int R = 6371; // Radius of the earth

    Double latDistance = deg2rad(lat2 - lat1);
    Double lonDistance = deg2rad(lon2 - lon1);
    Double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
            + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
            * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
    Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    double distance = R * c * 1000; // convert to meters

    double height = el1 - el2;
    distance = Math.pow(distance, 2) + Math.pow(height, 2);
    return Math.sqrt(distance);
}

private double deg2rad(double deg) {
    return (deg * Math.PI / 180.0);
}

The top voted answer has the following comment:投票最高的答案有以下评论:

"Why not Math.toRadians() instead of deg2rad()? It would be really self-containing." “为什么不用 Math.toRadians() 而不是 deg2rad()?它真的是自包含的。”

I looked up the Math.toRadians() method in the documentation and noticed this:我在文档中查找了 Math.toRadians() 方法并注意到了这一点:

"Converts an angle measured in degrees to an approximately equivalent angle measured in radians. The conversion from degrees to radians is generally inexact. " “将以度为单位的角度转换为以弧度为单位的近似等效角度。从度数到弧度的转换通常是不准确的。

  1. Is the top voted answer's deg2rad method more or less exact than the Math.toRadians() method?最高投票答案的 deg2rad 方法是否比 Math.toRadians() 方法更准确?
  2. Using the deg2rad method performs two arithmetic operations and one Math.Pi look up, its not clear how Math.toRadians() performs the convention.使用 deg2rad 方法执行两个算术运算和一个 Math.Pi 查找,尚不清楚 Math.toRadians() 如何执行约定。 Assuming that this distance calculation may be performed frequently and quick response to user input is desired, which conversion method would scale more efficiently?假设这种距离计算可能会经常执行并且需要对用户输入做出快速响应,那么哪种转换方法会更有效地缩放?

If the answer to question 1 is that the two methods have roughly the same inexactness/accuracy, I think that I would use Math.toRadians.如果问题 1 的答案是这两种方法具有大致相同的不精确性/准确性,我想我会使用 Math.toRadians。 Using Math.ToRadians makes the code more readable, and I assume that it would scale more efficiently as well.使用 Math.ToRadians 使代码更具可读性,我认为它也会更有效地扩展。

Math.toRadians is implemented like this: Math.toRadians是这样实现的:

public static double toRadians(double angdeg) {
    return angdeg / 180.0 * PI;
}

1) If there is a difference, it's negligible. 1) 如果有差异,则可以忽略不计。 Math.toRadians does the division first, while that answer does the multiplication first. Math.toRadians除法,而那个答案Math.toRadians乘法。

2) The only way to find out for sure is to test it, but I would expect that neither is faster since they both do the same thing. 2)确定确定的唯一方法是对其进行测试,但我希望两者都不是更快,因为它们都做同样的事情。

In Java 9, the implementations of toRadians and toDegrees were changed to this:在 Java 9 中, toRadianstoDegrees的实现更改为:

public static double toRadians(double angdeg) {
    return angdeg * DEGREES_TO_RADIANS;
}

public static double toDegrees(double angrad) {
    return angrad * RADIANS_TO_DEGREES;
}

where DEGREES_TO_RADIANS and RADIANS_TO_DEGREES are literal constants.其中DEGREES_TO_RADIANSRADIANS_TO_DEGREES是文字常量。 According to the following sources, this gives a 3-fold performance increase in a JMH micro-benchmark.根据以下来源,这使 JMH 微基准测试的性能提高了 3 倍。

(We can also infer that the JIT compiler is not performing an optimization that is equivalent to the above. I presume that is because such an optimization could alter the computation's results. That would make it incorrect in general . The JIT compiler probably cannot make the judgement which way gives more accurate results, and it certainly cannot judge if accuracy ... or reproducibility ... is the most important criterion.) (我们还可以推断 JIT 编译器没有执行与上述等效的优化。我认为这是因为这样的优化可能会改变计算结果。这通常会使其不正确。JIT 编译器可能无法使判断哪种方式给出的结果更准确,当然不能判断准确度……还是再现性……是最重要的标准。)

The JDK bug database entries that relate to this are:与此相关的 JDK 错误数据库条目是:


In summary, the answer for Java 9 and later is that the standard Math functions are faster than the alternative version.总之,Java 9 及更高版本的答案是标准Math函数比替代版本更快。 (Whether this was true in Java 8 and earlier is still untested ...) (这在 Java 8 及更早版本中是否属实尚未经过测试......)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM