Разница между BOOST_CHECK_CLOSE и BOOST_CHECK_CLOSE_FRACTION?

Кто-нибудь может описать разницу в поведении между BOOST_CHECK_CLOSE и BOOST_CHECK_CLOSE_FRACTION? Документация подразумевает, что оба макроса одинаково обрабатывают свой третий параметр, что заставляет меня подозревать, что документация неверна.

В частности, BOOST_CHECK_CLOSE_FRACTION дает мне некоторые странные результаты:

error in "...": difference between *expected{0} and *actual{-1.7763568394002506e-16} exceeds 9.9999999999999995e-07

Есть ли ошибка, потому что я ожидаю нулевого результата? Мне не удалось прочитать основные объявления макросов. Обратите внимание, что BOOST_CHECK_SMALL не подходит для моего варианта использования (сравнение двух векторов после операции линейной алгебры).


person Rhys Ulerich    schedule 07.07.2009    source источник


Ответы (3)


Согласно этому обсуждению, один (BOOST_CHECK_CLOSE) лечит третий параметр выражает проценты, а другой (BOOST_CHECK_CLOSE_FRACTION) интерпретирует его как выражение дроби. Таким образом, 0,01 в первом случае должно быть эквивалентно 0,0001 во втором.

Не уверен, что это объясняет вашу проблему - вы получаете такой же странный результат с BOOST_CHECK_CLOSE? Я не был бы шокирован, если бы 0 вызвал проблему, но у меня нет личного опыта работы с макросами.

person Richard Dunlap    schedule 07.07.2009
comment
Спасибо за ответ. Похоже, что проблема связана с нулем, и аналогичное поведение возникает с одним нулевым аргументом как для BOOST_CHECK_CLOSE, так и для BOOST_CHECK_CLOSE_FRACTION. - person Rhys Ulerich; 13.07.2009

Да. Ноль не "близок" ни к какому значению. Вместо этого вы можете использовать BOOST_CHECK_SMALL.

person Gennadiy Rozental    schedule 02.08.2009

@Gennadiy: Ноль может быть близок к любому маленькому значению. :-) Относительные различия растут сколь угодно большими, если ожидаемое значение очень близко к нулю.

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

void dbl_check_close(
    double expected, double observed, 
    double small, double pct_tol
) {
    if (std::fabs(expected) < small) {
        BOOST_CHECK_SMALL(observed, small);
    } else {
        BOOST_CHECK_CLOSE(expected, observed, pct_tol);
    }
}

Конечно, было бы здорово иметь макрос BOOST_CHECK_SMALL_OR_CLOSE, который делает это автоматически. Геннадий, возможно, мог бы поговорить с автором Boost.Test ;-)

person Laryx Decidua    schedule 18.11.2013