Java Math.toRadians(角度) vs 硬计算
Java Math.toRadians(angle) vs hard-calculated
这个问题与另一个 Whosebug 讨论有关distance between long&lat points
这是得票最多的答案中的代码:
/*
* 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);
}
投票最高的答案有以下评论:
"Why not Math.toRadians() instead of deg2rad()? It would be really self-containing."
我在 documentation 中查找了 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."
- 票数最高的答案的 deg2rad 方法是否比 Math.toRadians() 方法更精确?
- 使用 deg2rad 方法执行两次算术运算和一次 Math.Pi 查找,不清楚 Math.toRadians() 如何执行约定。假设这种距离计算可能会频繁执行,并且需要对用户输入做出快速响应,那么哪种转换方法的缩放效率更高?
如果问题1的答案是两种方法大致相同inexactness/accuracy,我想我会用Math.toRadians。使用 Math.ToRadians 使代码更具可读性,我认为它也会更有效地扩展。
Math.toRadians
是这样实现的:
public static double toRadians(double angdeg) {
return angdeg / 180.0 * PI;
}
1) 如果有差异,可以忽略不计。 Math.toRadians
先做除法,而那个答案先做乘法。
2) 确定答案的唯一方法是对其进行测试,但我希望两者都不会更快,因为它们都做同样的事情。
在Java 9中,toRadians
和toDegrees
的实现改为:
public static double toRadians(double angdeg) {
return angdeg * DEGREES_TO_RADIANS;
}
public static double toDegrees(double angrad) {
return angrad * RADIANS_TO_DEGREES;
}
其中 DEGREES_TO_RADIANS
和 RADIANS_TO_DEGREES
是文字常量。根据以下来源,这使 JMH 微基准测试的性能提高了 3 倍。
(我们还可以推断 JIT 编译器没有执行与上述等效的优化。我认为这是因为这样的优化可能会改变计算结果。这会使它不正确 一般来说。JIT 编译器可能无法判断哪种方式给出的结果更准确,而且它当然无法判断准确性...或可重复性...是否是最重要的标准。)
与此相关的 JDK 个错误数据库条目是:
总而言之,Java 9 及更高版本的答案是标准 Math
函数比替代版本更快。 (这在 Java 8 和更早版本中是否正确尚未测试...)
这个问题与另一个 Whosebug 讨论有关distance between long&lat points
这是得票最多的答案中的代码:
/*
* 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);
}
投票最高的答案有以下评论:
"Why not Math.toRadians() instead of deg2rad()? It would be really self-containing."
我在 documentation 中查找了 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."
- 票数最高的答案的 deg2rad 方法是否比 Math.toRadians() 方法更精确?
- 使用 deg2rad 方法执行两次算术运算和一次 Math.Pi 查找,不清楚 Math.toRadians() 如何执行约定。假设这种距离计算可能会频繁执行,并且需要对用户输入做出快速响应,那么哪种转换方法的缩放效率更高?
如果问题1的答案是两种方法大致相同inexactness/accuracy,我想我会用Math.toRadians。使用 Math.ToRadians 使代码更具可读性,我认为它也会更有效地扩展。
Math.toRadians
是这样实现的:
public static double toRadians(double angdeg) {
return angdeg / 180.0 * PI;
}
1) 如果有差异,可以忽略不计。 Math.toRadians
先做除法,而那个答案先做乘法。
2) 确定答案的唯一方法是对其进行测试,但我希望两者都不会更快,因为它们都做同样的事情。
在Java 9中,toRadians
和toDegrees
的实现改为:
public static double toRadians(double angdeg) {
return angdeg * DEGREES_TO_RADIANS;
}
public static double toDegrees(double angrad) {
return angrad * RADIANS_TO_DEGREES;
}
其中 DEGREES_TO_RADIANS
和 RADIANS_TO_DEGREES
是文字常量。根据以下来源,这使 JMH 微基准测试的性能提高了 3 倍。
(我们还可以推断 JIT 编译器没有执行与上述等效的优化。我认为这是因为这样的优化可能会改变计算结果。这会使它不正确 一般来说。JIT 编译器可能无法判断哪种方式给出的结果更准确,而且它当然无法判断准确性...或可重复性...是否是最重要的标准。)
与此相关的 JDK 个错误数据库条目是:
总而言之,Java 9 及更高版本的答案是标准 Math
函数比替代版本更快。 (这在 Java 8 和更早版本中是否正确尚未测试...)