У меня есть два вектора:
std::vector<double> calculatedValues = calculateValues();
std::vector<double> expectedValues = {1.1, 1.2};
я использую cpputest чтобы проверить, равны ли эти векторы:
CHECK_TRUE(calculatedValues == expectedValues)
Это работает. Однако мне интересно, не следует ли мне использовать некоторую терпимость, потому что в конце концов я сравниваю двойники.
Чтобы сравнить значения с плавающей запятой, вы должны сделать что-то вроде этого:
bool is_equal(double a, double b) {
return (abs(a-b)/b < 0.0001); // 0.00001 value can be a relative value
}
Вы можете адаптировать его для сравнения ваших векторов.
Да, вы должны использовать некоторый допуск, потому что операции с плавающей запятой не гарантируют одинаковые результаты на разных процессорах. Там может быть, например, ошибки округления.
Однако стандарты SSE / SSE2 обеспечивают воспроизводимую математику с плавающей точкой, поэтому вы можете рассмотреть возможность использования флага компиляции / ARCH: SSE2 в качестве альтернативы. Тем не менее, трудно гарантировать, что в приложении нигде не используется математика x87, поэтому будьте осторожны!
Вместо operator==
ты можешь использовать std::equal()
с обычаем эпсилон:
bool equal = std::equal(calculatedValues.begin(), calculatedValues.end(), expectedValues.begin(),
[](double value1, double value2)
{
constexpr double epsilon = 0.01; // Choose whatever you need here
return std::fabs(value1 - value2) < epsilon;
});
CHECK_TRUE(equal);