Метод Java Math.cos () не возвращает 0, когда ожидается - PullRequest
8 голосов
/ 10 февраля 2010

Использование Java на ПК с Windows 7 (не уверен, имеет ли это значение) и вызов Math.cos () для значений, которые должны возвращать 0 (например, pi / 2), вместо этого возвращает небольшие значения, но небольшие значения, если недопонимание, намного больше, чем 1 ulp от нуля.

Math.cos(Math.PI/2) = 6.123233995736766E-17
Math.ulp(Math.cos(Math.PI/2)) = 1.232595164407831E-32

Это на самом деле в пределах 1 ульпы, и я просто запутался? И будет ли это приемлемым методом-оберткой для устранения этой незначительной неточности?

public static double cos(double a){
    double temp = Math.abs(a % Math.PI);
    if(temp == Math.PI/2)
        return 0;
    return Math.cos(a);
}

Ответы [ 3 ]

11 голосов
/ 10 февраля 2010

Не забывайте, что Math.PI/2 является приблизительным.Это не будет точно pi / 2, поэтому результат cos(Math.PI/2) не будет точно 0. Math.cos может возвращать довольно точную версиюкосинус точного значения, возвращенного вычислением Math.PI/2.

7 голосов
/ 10 февраля 2010

Вы никогда не должны использовать == с двойными числами. Вы всегда должны делать это в пределах допустимой погрешности. 10 -17 хорошая точность, если вы спросите меня. Значение Ulp в 10 -32 является просто точным двойным числом, имеющим порядок 10 -17 , а 2.220446049250313E-16 - это точность числа в 10 0. величина.

2 голосов
/ 10 февраля 2010

Это распространенная ошибка, когда вы начинаете, по этой ссылке очень техническое обсуждение причин. http://docs.sun.com/source/806-3568/ncg_goldberg.html

Но в простейшей форме, точно так же, как мы не можем точно представить 1/3 в десятичной системе, есть значения, которые не могут быть точно представлены в двоичной системе

...