Разница между 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
не подходит для моего варианта использования (сравнение двух векторов после операции линейной алгебры).
Ответы
Ответ 1
В соответствии с это обсуждение, один (BOOST_CHECK_CLOSE
) рассматривает третий параметр как выражение процента, тогда как другой (BOOST_CHECK_CLOSE_FRACTION
) рассматривает его как выражение фракции. Итак,.01 в первом должен быть эквивалентен .0001 во втором.
Не уверен, что это объясняет вашу проблему - вы получаете тот же нечетный результат с BOOST_CHECK_CLOSE
? Я бы не был шокирован, если 0 вызвал проблему, но у меня нет первого опыта работы с макросами.
Ответ 2
Да. Zero не является "близким" к любому значению. Вместо этого вы можете использовать BOOST_CHECK_SMALL.
Ответ 3
@Gennadiy: Zero может быть близким к любому небольшому значению.:-) Относительные различия растут произвольно большими, если ожидаемое значение очень близко к нулю.
Вот обходная функция, которую я использую для unit-test double values: если ожидаемое значение очень мало или равно нулю, я проверяю малость наблюдаемого значения, в противном случае проверяю близость:
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; -)