繁体   English   中英

处理三角函数时的浮点精度

[英]Floating-point precision when dealing with trigonometric functions

我有一个Java类,使用java.lang.Math处理许多三角函数。 以下代码确定0度和180度的平均方向。 结果应该是NaN,因为0度和180度是相反的方向,相互抵消。 但是,当我这样做时:

double[] angles = {0, 180};
double sines = 0;
double cosines = 0;
double avg;
for (int i = 0; i < angles.length; i++) {
    double rad = Math.toRadians(angles[i]);
    sines += Math.sin(rad);
    cosines += Math.cos(rad);
}
double sin = sines / angles.length;
double cos = cosines / angles.length;
System.out.println("Avg sin: " + sin + "\nAvg cos: " + cos); // sin != 0 but it should
double avgRad = Math.atan2(sin, cos);
avg = Math.toDegrees(avgRad);
System.out.println("Average: " + avg);

avg等于90.0而不是NaN 这是因为180度和0度的平均正弦导致非常小但正数(由于浮点精度的工作方式)。 如果您运行上面的代码,您将看到我的意思。 我怎样才能避免这种缺乏精确性? 我知道我可以围绕平均的正弦和余弦以及最终结果,但这对我来说似乎有点不合适。

我认为你必须在使用sin / cos / tan之前直接考虑平均角度(使用mod 360)。 话虽这么说,我认为,你在你的代码中得到你想要的东西是正确的方向(除了可能在最后一个例子中的负号翻转)。

~> java Main 0 180
Avg sin: 6.123233995736766E-17
Avg cos: 0.0
Average: 90.0

~> java Main 0 179
Avg sin: 0.00872620321864172
Avg cos: 7.615242180436521E-5
Average: 89.50000000000011

~> java Main 1 179
Avg sin: 0.017452406437283477
Avg cos: 0.0
Average: 90.0

~> java Main 1 180
Avg sin: 0.008726203218641817
Avg cos: -7.615242180436521E-5
Average: 90.49999999999991

~> java Main 1 181
Avg sin: 1.5959455978986625E-16
Avg cos: 0.0
Average: 90.0

~> java Main 1 182
Avg sin: -0.008723545132608694
Avg cos: 2.2843406864775373E-4
Average: -88.50000000000001

暂无
暂无

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

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