У меня есть класс 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 градусов приводит к очень маленькому, но положительному числу (из-за того, что работает точность с плавающей точкой). Если вы запустите вышеуказанный код, вы увидите, что я имею в виду. Как я могу избежать этого недостатка точности? Я знаю, что могу обойти средние синусы и косинусы, а также конечный результат, но для меня это кажется немного нелогичным.
Математика с плавающей точкой подвержена ошибкам округления. Живи с этим. – Mick
Я знаю, что это так. Я спрашиваю, как обойти это. – Kootling
Что именно вы пытаетесь сделать? – Mick