О двойниках и равенстве - PullRequest
       35

О двойниках и равенстве

3 голосов
/ 17 января 2012

Один из моих методов возвращает double. При тестировании этого метода как части моего jUnit я заметил следующую странность:

    String a = "someString";
    String b = "someDifferentString";

    double result = c.getScore(a, b, true);
    System.out.println(result); // prints 0.0

    assert (result > 0.0); // Test passes

Итак .. Я спрашиваю вас, как 0.0 может быть больше 0.0? Почему result > 0.0 оценивается как true?

Ответы [ 3 ]

9 голосов
/ 17 января 2012

assert является ключевым словом Java.Вам нужно assertTrue(result > 0.0)

7 голосов
/ 17 января 2012

Тебя волнует математика с плавающей точкой.0.0, вероятно, не абсолютный 0.0, но 0.00000000000000009 или что-то действительно очень маленькое.Почему это?Хорошо математика с плавающей точкой дискретна в компьютерах.Но в действительности математика с плавающей точкой непрерывна, и, следовательно, мы имеем несоответствие между дискретным (цифровым) и непрерывным (аналоговым).Ошибки начинают ползти, заставляя вещи немного дрейфовать.Если вы хотите узнать больше, прочитайте это:

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

В junit есть методы, специально разработанные для сравнения значений типа float / double, которые допускают допуск (например, assertEquals (ожидаемое двойное, двойное действительное)двойной эпсилон)).Используйте их, и вы должны стабилизировать свой тест перед лицом крошечных ошибок, которые вы видите.Помните, что не устанавливайте их слишком высоко, потому что ваша общая ошибка должна быть очень маленькой.

См. Также этот вопрос об этом:

JUnit assertEquals (ожидаемое двойное, действительное в два раза, двойноеэпсилон)

7 голосов
/ 17 января 2012

Сравнение двойных чисел вообще опасно, потому что представления с плавающей точкой по определению неточны.Кроме того, вы должны быть осторожны при выводе значений, так как печатное представление часто округляется по сравнению с фактическим сохраненным представлением.

При этом @JBNizet прибил его - вы пишете утверждение Java, а нетест JUnit!

...