Как проверить равенство двух чисел с плавающей точкой (float)?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Сравнивать напрямую оператором == не рекомендуется из-за особенностей представления и округления. Вместо этого следует проверить, находится ли абсолютное значение разности чисел в пределах некоторого малого порога (эпсилон).
bool are_equal(float a, float b, float epsilon = 0.00001f) {
return std::abs(a - b) < epsilon;
}
Более устойчивый подход учитывает относительную ошибку, особенно при сравнении очень больших или очень маленьких чисел:
#include <cmath>
#include <limits>
bool are_equal_robust(float a, float b, float epsilon = std::numeric_limits<float>::epsilon()) {
// Сравниваем разницу с учетом масштаба чисел
// Важно обрабатывать случаи с нулем и бесконечностью отдельно
if (a == b) {
return true; // Обработка случаев a=b (включая инфинити и NaN, если они равны себе – что не так для NaN, но для инфинити да)
}
float absolute_difference = std::abs(a - b);
float max_abs = std::max(std::abs(a), std::abs(b));
if (max_abs < epsilon) {
return absolute_difference < epsilon; // Оба числа близки к нулю
} else {
return absolute_difference / max_abs < epsilon; // Сравнение относительной разности
}
}
Выбор epsilon зависит от требуемой точности и диапазона сравниваемых значений. std::numeric_limits<float>::epsilon() представляет наименьшее число, такое что 1.0 + epsilon отлично от 1.0.
Важно помнить, что сравнение NaN (Not a Number) всегда возвращает false, включая сравнение NaN с самим собой (nan == nan всегда false). Если требуется обрабатывать NaN, это должно делаться отдельно.